ActivityManagerService.java revision 9c211a339689a2e54da3315ccdbf22add472c76a
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.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.internal.util.ProgressReporter;
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.KeyguardManager;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.admin.DevicePolicyManagerInternal;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
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.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.text.format.DateUtils;
200import android.text.format.Time;
201import android.util.ArrayMap;
202import android.util.ArraySet;
203import android.util.AtomicFile;
204import android.util.DebugUtils;
205import android.util.EventLog;
206import android.util.LocaleList;
207import android.util.Log;
208import android.util.Pair;
209import android.util.PrintWriterPrinter;
210import android.util.Slog;
211import android.util.SparseArray;
212import android.util.TimeUtils;
213import android.util.Xml;
214import android.view.Display;
215import android.view.Gravity;
216import android.view.LayoutInflater;
217import android.view.View;
218import android.view.WindowManager;
219
220import java.io.File;
221import java.io.FileDescriptor;
222import java.io.FileInputStream;
223import java.io.FileNotFoundException;
224import java.io.FileOutputStream;
225import java.io.IOException;
226import java.io.InputStreamReader;
227import java.io.PrintWriter;
228import java.io.StringWriter;
229import java.lang.ref.WeakReference;
230import java.nio.charset.StandardCharsets;
231import java.util.ArrayList;
232import java.util.Arrays;
233import java.util.Collections;
234import java.util.Comparator;
235import java.util.HashMap;
236import java.util.HashSet;
237import java.util.Iterator;
238import java.util.List;
239import java.util.Locale;
240import java.util.Map;
241import java.util.Set;
242import java.util.concurrent.atomic.AtomicBoolean;
243import java.util.concurrent.atomic.AtomicLong;
244
245import dalvik.system.VMRuntime;
246
247import libcore.io.IoUtils;
248import libcore.util.EmptyArray;
249
250import static android.Manifest.permission.INTERACT_ACROSS_USERS;
251import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
252import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
253import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
254import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
255import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
256import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
257import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
258import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.HOME_STACK_ID;
261import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
262import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
263import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
264import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
265import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
266import static android.content.pm.PackageManager.GET_PROVIDERS;
267import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
268import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
269import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
270import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
271import static android.content.pm.PackageManager.PERMISSION_GRANTED;
272import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
273import static android.provider.Settings.Global.DEBUG_APP;
274import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
277import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
278import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
279import static android.provider.Settings.System.FONT_SCALE;
280import static com.android.internal.util.XmlUtils.readBooleanAttribute;
281import static com.android.internal.util.XmlUtils.readIntAttribute;
282import static com.android.internal.util.XmlUtils.readLongAttribute;
283import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
284import static com.android.internal.util.XmlUtils.writeIntAttribute;
285import static com.android.internal.util.XmlUtils.writeLongAttribute;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
343import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
344import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
345import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
346import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
347import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
348import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
349import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
350import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
351import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
352import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
354import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
355import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
356import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
357import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
359import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
360import static org.xmlpull.v1.XmlPullParser.START_TAG;
361
362public final class ActivityManagerService extends ActivityManagerNative
363        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
364
365    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
366    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
367    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
368    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
369    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
370    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
371    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
372    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
373    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
374    private static final String TAG_LRU = TAG + POSTFIX_LRU;
375    private static final String TAG_MU = TAG + POSTFIX_MU;
376    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
377    private static final String TAG_POWER = TAG + POSTFIX_POWER;
378    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
379    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
380    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
381    private static final String TAG_PSS = TAG + POSTFIX_PSS;
382    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
383    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
384    private static final String TAG_STACK = TAG + POSTFIX_STACK;
385    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
386    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
387    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
388    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
389    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
390
391    /** Control over CPU and battery monitoring */
392    // write battery stats every 30 minutes.
393    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
394    static final boolean MONITOR_CPU_USAGE = true;
395    // don't sample cpu less than every 5 seconds.
396    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
397    // wait possibly forever for next cpu sample.
398    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
399    static final boolean MONITOR_THREAD_CPU_USAGE = false;
400
401    // The flags that are set for all calls we make to the package manager.
402    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
403
404    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
405
406    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
407
408    // Amount of time after a call to stopAppSwitches() during which we will
409    // prevent further untrusted switches from happening.
410    static final long APP_SWITCH_DELAY_TIME = 5*1000;
411
412    // How long we wait for a launched process to attach to the activity manager
413    // before we decide it's never going to come up for real.
414    static final int PROC_START_TIMEOUT = 10*1000;
415    // How long we wait for an attached process to publish its content providers
416    // before we decide it must be hung.
417    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
418
419    // How long we will retain processes hosting content providers in the "last activity"
420    // state before allowing them to drop down to the regular cached LRU list.  This is
421    // to avoid thrashing of provider processes under low memory situations.
422    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
423
424    // How long we wait for a launched process to attach to the activity manager
425    // before we decide it's never going to come up for real, when the process was
426    // started with a wrapper for instrumentation (such as Valgrind) because it
427    // could take much longer than usual.
428    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
429
430    // How long to wait after going idle before forcing apps to GC.
431    static final int GC_TIMEOUT = 5*1000;
432
433    // The minimum amount of time between successive GC requests for a process.
434    static final int GC_MIN_INTERVAL = 60*1000;
435
436    // The minimum amount of time between successive PSS requests for a process.
437    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
438
439    // The minimum amount of time between successive PSS requests for a process
440    // when the request is due to the memory state being lowered.
441    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
442
443    // The rate at which we check for apps using excessive power -- 15 mins.
444    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
445
446    // The minimum sample duration we will allow before deciding we have
447    // enough data on wake locks to start killing things.
448    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
449
450    // The minimum sample duration we will allow before deciding we have
451    // enough data on CPU usage to start killing things.
452    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
453
454    // How long we allow a receiver to run before giving up on it.
455    static final int BROADCAST_FG_TIMEOUT = 10*1000;
456    static final int BROADCAST_BG_TIMEOUT = 60*1000;
457
458    // How long we wait until we timeout on key dispatching.
459    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
460
461    // How long we wait until we timeout on key dispatching during instrumentation.
462    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
463
464    // This is the amount of time an app needs to be running a foreground service before
465    // we will consider it to be doing interaction for usage stats.
466    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
467
468    // Maximum amount of time we will allow to elapse before re-reporting usage stats
469    // interaction with foreground processes.
470    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
471
472    // This is the amount of time we allow an app to settle after it goes into the background,
473    // before we start restricting what it can do.
474    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
475
476    // How long to wait in getAssistContextExtras for the activity and foreground services
477    // to respond with the result.
478    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
479
480    // How long top wait when going through the modern assist (which doesn't need to block
481    // on getting this result before starting to launch its UI).
482    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
483
484    // Maximum number of persisted Uri grants a package is allowed
485    static final int MAX_PERSISTED_URI_GRANTS = 128;
486
487    static final int MY_PID = Process.myPid();
488
489    static final String[] EMPTY_STRING_ARRAY = new String[0];
490
491    // How many bytes to write into the dropbox log before truncating
492    static final int DROPBOX_MAX_SIZE = 256 * 1024;
493
494    // Access modes for handleIncomingUser.
495    static final int ALLOW_NON_FULL = 0;
496    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
497    static final int ALLOW_FULL_ONLY = 2;
498
499    // Delay in notifying task stack change listeners (in millis)
500    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
501
502    // Necessary ApplicationInfo flags to mark an app as persistent
503    private static final int PERSISTENT_MASK =
504            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
505
506    // Intent sent when remote bugreport collection has been completed
507    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
508            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
509
510    // Delay to disable app launch boost
511    static final int APP_BOOST_MESSAGE_DELAY = 3000;
512    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
513    static final int APP_BOOST_TIMEOUT = 2500;
514
515    // Used to indicate that a task is removed it should also be removed from recents.
516    private static final boolean REMOVE_FROM_RECENTS = true;
517    // Used to indicate that an app transition should be animated.
518    static final boolean ANIMATE = true;
519
520    // Determines whether to take full screen screenshots
521    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
522    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
523
524    private static native int nativeMigrateToBoost();
525    private static native int nativeMigrateFromBoost();
526    private boolean mIsBoosted = false;
527    private long mBoostStartTime = 0;
528
529    /** All system services */
530    SystemServiceManager mSystemServiceManager;
531
532    private Installer mInstaller;
533
534    /** Run all ActivityStacks through this */
535    final ActivityStackSupervisor mStackSupervisor;
536
537    final ActivityStarter mActivityStarter;
538
539    /** Task stack change listeners. */
540    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
541            new RemoteCallbackList<ITaskStackListener>();
542
543    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
544
545    public IntentFirewall mIntentFirewall;
546
547    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
548    // default actuion automatically.  Important for devices without direct input
549    // devices.
550    private boolean mShowDialogs = true;
551    private boolean mInVrMode = false;
552
553    BroadcastQueue mFgBroadcastQueue;
554    BroadcastQueue mBgBroadcastQueue;
555    // Convenient for easy iteration over the queues. Foreground is first
556    // so that dispatch of foreground broadcasts gets precedence.
557    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
558
559    BroadcastQueue broadcastQueueForIntent(Intent intent) {
560        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
561        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
562                "Broadcast intent " + intent + " on "
563                + (isFg ? "foreground" : "background") + " queue");
564        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
565    }
566
567    /**
568     * Activity we have told the window manager to have key focus.
569     */
570    ActivityRecord mFocusedActivity = null;
571
572    /**
573     * User id of the last activity mFocusedActivity was set to.
574     */
575    private int mLastFocusedUserId;
576
577    /**
578     * If non-null, we are tracking the time the user spends in the currently focused app.
579     */
580    private AppTimeTracker mCurAppTimeTracker;
581
582    /**
583     * List of intents that were used to start the most recent tasks.
584     */
585    final RecentTasks mRecentTasks;
586
587    /**
588     * For addAppTask: cached of the last activity component that was added.
589     */
590    ComponentName mLastAddedTaskComponent;
591
592    /**
593     * For addAppTask: cached of the last activity uid that was added.
594     */
595    int mLastAddedTaskUid;
596
597    /**
598     * For addAppTask: cached of the last ActivityInfo that was added.
599     */
600    ActivityInfo mLastAddedTaskActivity;
601
602    /**
603     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
604     */
605    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
606
607    /**
608     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
609     */
610    String mDeviceOwnerName;
611
612    final UserController mUserController;
613
614    final AppErrors mAppErrors;
615
616    boolean mDoingSetFocusedActivity;
617
618    public boolean canShowErrorDialogs() {
619        return mShowDialogs && !mSleeping && !mShuttingDown;
620    }
621
622    public class PendingAssistExtras extends Binder implements Runnable {
623        public final ActivityRecord activity;
624        public final Bundle extras;
625        public final Intent intent;
626        public final String hint;
627        public final IResultReceiver receiver;
628        public final int userHandle;
629        public boolean haveResult = false;
630        public Bundle result = null;
631        public AssistStructure structure = null;
632        public AssistContent content = null;
633        public Bundle receiverExtras;
634
635        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
636                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
637            activity = _activity;
638            extras = _extras;
639            intent = _intent;
640            hint = _hint;
641            receiver = _receiver;
642            receiverExtras = _receiverExtras;
643            userHandle = _userHandle;
644        }
645        @Override
646        public void run() {
647            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
648            synchronized (this) {
649                haveResult = true;
650                notifyAll();
651            }
652            pendingAssistExtrasTimedOut(this);
653        }
654    }
655
656    final ArrayList<PendingAssistExtras> mPendingAssistExtras
657            = new ArrayList<PendingAssistExtras>();
658
659    /**
660     * Process management.
661     */
662    final ProcessList mProcessList = new ProcessList();
663
664    /**
665     * All of the applications we currently have running organized by name.
666     * The keys are strings of the application package name (as
667     * returned by the package manager), and the keys are ApplicationRecord
668     * objects.
669     */
670    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
671
672    /**
673     * Tracking long-term execution of processes to look for abuse and other
674     * bad app behavior.
675     */
676    final ProcessStatsService mProcessStats;
677
678    /**
679     * The currently running isolated processes.
680     */
681    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
682
683    /**
684     * Counter for assigning isolated process uids, to avoid frequently reusing the
685     * same ones.
686     */
687    int mNextIsolatedProcessUid = 0;
688
689    /**
690     * The currently running heavy-weight process, if any.
691     */
692    ProcessRecord mHeavyWeightProcess = null;
693
694    /**
695     * All of the processes we currently have running organized by pid.
696     * The keys are the pid running the application.
697     *
698     * <p>NOTE: This object is protected by its own lock, NOT the global
699     * activity manager lock!
700     */
701    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
702
703    /**
704     * All of the processes that have been forced to be foreground.  The key
705     * is the pid of the caller who requested it (we hold a death
706     * link on it).
707     */
708    abstract class ForegroundToken implements IBinder.DeathRecipient {
709        int pid;
710        IBinder token;
711    }
712    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
713
714    /**
715     * List of records for processes that someone had tried to start before the
716     * system was ready.  We don't start them at that point, but ensure they
717     * are started by the time booting is complete.
718     */
719    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
720
721    /**
722     * List of persistent applications that are in the process
723     * of being started.
724     */
725    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
726
727    /**
728     * Processes that are being forcibly torn down.
729     */
730    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
731
732    /**
733     * List of running applications, sorted by recent usage.
734     * The first entry in the list is the least recently used.
735     */
736    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
737
738    /**
739     * Where in mLruProcesses that the processes hosting activities start.
740     */
741    int mLruProcessActivityStart = 0;
742
743    /**
744     * Where in mLruProcesses that the processes hosting services start.
745     * This is after (lower index) than mLruProcessesActivityStart.
746     */
747    int mLruProcessServiceStart = 0;
748
749    /**
750     * List of processes that should gc as soon as things are idle.
751     */
752    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
753
754    /**
755     * Processes we want to collect PSS data from.
756     */
757    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
758
759    private boolean mBinderTransactionTrackingEnabled = false;
760
761    /**
762     * Last time we requested PSS data of all processes.
763     */
764    long mLastFullPssTime = SystemClock.uptimeMillis();
765
766    /**
767     * If set, the next time we collect PSS data we should do a full collection
768     * with data from native processes and the kernel.
769     */
770    boolean mFullPssPending = false;
771
772    /**
773     * This is the process holding what we currently consider to be
774     * the "home" activity.
775     */
776    ProcessRecord mHomeProcess;
777
778    /**
779     * This is the process holding the activity the user last visited that
780     * is in a different process from the one they are currently in.
781     */
782    ProcessRecord mPreviousProcess;
783
784    /**
785     * The time at which the previous process was last visible.
786     */
787    long mPreviousProcessVisibleTime;
788
789    /**
790     * Track all uids that have actively running processes.
791     */
792    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
793
794    /**
795     * This is for verifying the UID report flow.
796     */
797    static final boolean VALIDATE_UID_STATES = true;
798    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
799
800    /**
801     * Packages that the user has asked to have run in screen size
802     * compatibility mode instead of filling the screen.
803     */
804    final CompatModePackages mCompatModePackages;
805
806    /**
807     * Set of IntentSenderRecord objects that are currently active.
808     */
809    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
810            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
811
812    /**
813     * Fingerprints (hashCode()) of stack traces that we've
814     * already logged DropBox entries for.  Guarded by itself.  If
815     * something (rogue user app) forces this over
816     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
817     */
818    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
819    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
820
821    /**
822     * Strict Mode background batched logging state.
823     *
824     * The string buffer is guarded by itself, and its lock is also
825     * used to determine if another batched write is already
826     * in-flight.
827     */
828    private final StringBuilder mStrictModeBuffer = new StringBuilder();
829
830    /**
831     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
832     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
833     */
834    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
835
836    /**
837     * Resolver for broadcast intents to registered receivers.
838     * Holds BroadcastFilter (subclass of IntentFilter).
839     */
840    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
841            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
842        @Override
843        protected boolean allowFilterResult(
844                BroadcastFilter filter, List<BroadcastFilter> dest) {
845            IBinder target = filter.receiverList.receiver.asBinder();
846            for (int i = dest.size() - 1; i >= 0; i--) {
847                if (dest.get(i).receiverList.receiver.asBinder() == target) {
848                    return false;
849                }
850            }
851            return true;
852        }
853
854        @Override
855        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
856            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
857                    || userId == filter.owningUserId) {
858                return super.newResult(filter, match, userId);
859            }
860            return null;
861        }
862
863        @Override
864        protected BroadcastFilter[] newArray(int size) {
865            return new BroadcastFilter[size];
866        }
867
868        @Override
869        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
870            return packageName.equals(filter.packageName);
871        }
872    };
873
874    /**
875     * State of all active sticky broadcasts per user.  Keys are the action of the
876     * sticky Intent, values are an ArrayList of all broadcasted intents with
877     * that action (which should usually be one).  The SparseArray is keyed
878     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
879     * for stickies that are sent to all users.
880     */
881    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
882            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
883
884    final ActiveServices mServices;
885
886    final static class Association {
887        final int mSourceUid;
888        final String mSourceProcess;
889        final int mTargetUid;
890        final ComponentName mTargetComponent;
891        final String mTargetProcess;
892
893        int mCount;
894        long mTime;
895
896        int mNesting;
897        long mStartTime;
898
899        // states of the source process when the bind occurred.
900        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
901        long mLastStateUptime;
902        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
903                - ActivityManager.MIN_PROCESS_STATE+1];
904
905        Association(int sourceUid, String sourceProcess, int targetUid,
906                ComponentName targetComponent, String targetProcess) {
907            mSourceUid = sourceUid;
908            mSourceProcess = sourceProcess;
909            mTargetUid = targetUid;
910            mTargetComponent = targetComponent;
911            mTargetProcess = targetProcess;
912        }
913    }
914
915    /**
916     * When service association tracking is enabled, this is all of the associations we
917     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
918     * -> association data.
919     */
920    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
921            mAssociations = new SparseArray<>();
922    boolean mTrackingAssociations;
923
924    /**
925     * Backup/restore process management
926     */
927    String mBackupAppName = null;
928    BackupRecord mBackupTarget = null;
929
930    final ProviderMap mProviderMap;
931
932    /**
933     * List of content providers who have clients waiting for them.  The
934     * application is currently being launched and the provider will be
935     * removed from this list once it is published.
936     */
937    final ArrayList<ContentProviderRecord> mLaunchingProviders
938            = new ArrayList<ContentProviderRecord>();
939
940    /**
941     * File storing persisted {@link #mGrantedUriPermissions}.
942     */
943    private final AtomicFile mGrantFile;
944
945    /** XML constants used in {@link #mGrantFile} */
946    private static final String TAG_URI_GRANTS = "uri-grants";
947    private static final String TAG_URI_GRANT = "uri-grant";
948    private static final String ATTR_USER_HANDLE = "userHandle";
949    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
950    private static final String ATTR_TARGET_USER_ID = "targetUserId";
951    private static final String ATTR_SOURCE_PKG = "sourcePkg";
952    private static final String ATTR_TARGET_PKG = "targetPkg";
953    private static final String ATTR_URI = "uri";
954    private static final String ATTR_MODE_FLAGS = "modeFlags";
955    private static final String ATTR_CREATED_TIME = "createdTime";
956    private static final String ATTR_PREFIX = "prefix";
957
958    /**
959     * Global set of specific {@link Uri} permissions that have been granted.
960     * This optimized lookup structure maps from {@link UriPermission#targetUid}
961     * to {@link UriPermission#uri} to {@link UriPermission}.
962     */
963    @GuardedBy("this")
964    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
965            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
966
967    public static class GrantUri {
968        public final int sourceUserId;
969        public final Uri uri;
970        public boolean prefix;
971
972        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
973            this.sourceUserId = sourceUserId;
974            this.uri = uri;
975            this.prefix = prefix;
976        }
977
978        @Override
979        public int hashCode() {
980            int hashCode = 1;
981            hashCode = 31 * hashCode + sourceUserId;
982            hashCode = 31 * hashCode + uri.hashCode();
983            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
984            return hashCode;
985        }
986
987        @Override
988        public boolean equals(Object o) {
989            if (o instanceof GrantUri) {
990                GrantUri other = (GrantUri) o;
991                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
992                        && prefix == other.prefix;
993            }
994            return false;
995        }
996
997        @Override
998        public String toString() {
999            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1000            if (prefix) result += " [prefix]";
1001            return result;
1002        }
1003
1004        public String toSafeString() {
1005            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1006            if (prefix) result += " [prefix]";
1007            return result;
1008        }
1009
1010        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1011            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1012                    ContentProvider.getUriWithoutUserId(uri), false);
1013        }
1014    }
1015
1016    CoreSettingsObserver mCoreSettingsObserver;
1017
1018    FontScaleSettingObserver mFontScaleSettingObserver;
1019
1020    private final class FontScaleSettingObserver extends ContentObserver {
1021        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1022
1023        public FontScaleSettingObserver() {
1024            super(mHandler);
1025            ContentResolver resolver = mContext.getContentResolver();
1026            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1027        }
1028
1029        @Override
1030        public void onChange(boolean selfChange, Uri uri) {
1031            if (mFontScaleUri.equals(uri)) {
1032                updateFontScaleIfNeeded();
1033            }
1034        }
1035    }
1036
1037    /**
1038     * Thread-local storage used to carry caller permissions over through
1039     * indirect content-provider access.
1040     */
1041    private class Identity {
1042        public final IBinder token;
1043        public final int pid;
1044        public final int uid;
1045
1046        Identity(IBinder _token, int _pid, int _uid) {
1047            token = _token;
1048            pid = _pid;
1049            uid = _uid;
1050        }
1051    }
1052
1053    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1054
1055    /**
1056     * All information we have collected about the runtime performance of
1057     * any user id that can impact battery performance.
1058     */
1059    final BatteryStatsService mBatteryStatsService;
1060
1061    /**
1062     * Information about component usage
1063     */
1064    UsageStatsManagerInternal mUsageStatsService;
1065
1066    /**
1067     * Access to DeviceIdleController service.
1068     */
1069    DeviceIdleController.LocalService mLocalDeviceIdleController;
1070
1071    /**
1072     * Information about and control over application operations
1073     */
1074    final AppOpsService mAppOpsService;
1075
1076    /**
1077     * Current configuration information.  HistoryRecord objects are given
1078     * a reference to this object to indicate which configuration they are
1079     * currently running in, so this object must be kept immutable.
1080     */
1081    Configuration mConfiguration = new Configuration();
1082
1083    /**
1084     * Current sequencing integer of the configuration, for skipping old
1085     * configurations.
1086     */
1087    int mConfigurationSeq = 0;
1088
1089    boolean mSuppressResizeConfigChanges = false;
1090
1091    /**
1092     * Hardware-reported OpenGLES version.
1093     */
1094    final int GL_ES_VERSION;
1095
1096    /**
1097     * List of initialization arguments to pass to all processes when binding applications to them.
1098     * For example, references to the commonly used services.
1099     */
1100    HashMap<String, IBinder> mAppBindArgs;
1101
1102    /**
1103     * Temporary to avoid allocations.  Protected by main lock.
1104     */
1105    final StringBuilder mStringBuilder = new StringBuilder(256);
1106
1107    /**
1108     * Used to control how we initialize the service.
1109     */
1110    ComponentName mTopComponent;
1111    String mTopAction = Intent.ACTION_MAIN;
1112    String mTopData;
1113
1114    volatile boolean mProcessesReady = false;
1115    volatile boolean mSystemReady = false;
1116    volatile boolean mOnBattery = false;
1117    volatile int mFactoryTest;
1118
1119    @GuardedBy("this") boolean mBooting = false;
1120    @GuardedBy("this") boolean mCallFinishBooting = false;
1121    @GuardedBy("this") boolean mBootAnimationComplete = false;
1122    @GuardedBy("this") boolean mLaunchWarningShown = false;
1123    @GuardedBy("this") boolean mCheckedForSetup = false;
1124
1125    Context mContext;
1126
1127    /**
1128     * The time at which we will allow normal application switches again,
1129     * after a call to {@link #stopAppSwitches()}.
1130     */
1131    long mAppSwitchesAllowedTime;
1132
1133    /**
1134     * This is set to true after the first switch after mAppSwitchesAllowedTime
1135     * is set; any switches after that will clear the time.
1136     */
1137    boolean mDidAppSwitch;
1138
1139    /**
1140     * Last time (in realtime) at which we checked for power usage.
1141     */
1142    long mLastPowerCheckRealtime;
1143
1144    /**
1145     * Last time (in uptime) at which we checked for power usage.
1146     */
1147    long mLastPowerCheckUptime;
1148
1149    /**
1150     * Set while we are wanting to sleep, to prevent any
1151     * activities from being started/resumed.
1152     */
1153    private boolean mSleeping = false;
1154
1155    /**
1156     * The process state used for processes that are running the top activities.
1157     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1158     */
1159    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1160
1161    /**
1162     * Set while we are running a voice interaction.  This overrides
1163     * sleeping while it is active.
1164     */
1165    private IVoiceInteractionSession mRunningVoice;
1166
1167    /**
1168     * For some direct access we need to power manager.
1169     */
1170    PowerManagerInternal mLocalPowerManager;
1171
1172    /**
1173     * We want to hold a wake lock while running a voice interaction session, since
1174     * this may happen with the screen off and we need to keep the CPU running to
1175     * be able to continue to interact with the user.
1176     */
1177    PowerManager.WakeLock mVoiceWakeLock;
1178
1179    /**
1180     * State of external calls telling us if the device is awake or asleep.
1181     */
1182    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1183
1184    /**
1185     * A list of tokens that cause the top activity to be put to sleep.
1186     * They are used by components that may hide and block interaction with underlying
1187     * activities.
1188     */
1189    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1190
1191    static final int LOCK_SCREEN_HIDDEN = 0;
1192    static final int LOCK_SCREEN_LEAVING = 1;
1193    static final int LOCK_SCREEN_SHOWN = 2;
1194    /**
1195     * State of external call telling us if the lock screen is shown.
1196     */
1197    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1198
1199    /**
1200     * Set if we are shutting down the system, similar to sleeping.
1201     */
1202    boolean mShuttingDown = false;
1203
1204    /**
1205     * Current sequence id for oom_adj computation traversal.
1206     */
1207    int mAdjSeq = 0;
1208
1209    /**
1210     * Current sequence id for process LRU updating.
1211     */
1212    int mLruSeq = 0;
1213
1214    /**
1215     * Keep track of the non-cached/empty process we last found, to help
1216     * determine how to distribute cached/empty processes next time.
1217     */
1218    int mNumNonCachedProcs = 0;
1219
1220    /**
1221     * Keep track of the number of cached hidden procs, to balance oom adj
1222     * distribution between those and empty procs.
1223     */
1224    int mNumCachedHiddenProcs = 0;
1225
1226    /**
1227     * Keep track of the number of service processes we last found, to
1228     * determine on the next iteration which should be B services.
1229     */
1230    int mNumServiceProcs = 0;
1231    int mNewNumAServiceProcs = 0;
1232    int mNewNumServiceProcs = 0;
1233
1234    /**
1235     * Allow the current computed overall memory level of the system to go down?
1236     * This is set to false when we are killing processes for reasons other than
1237     * memory management, so that the now smaller process list will not be taken as
1238     * an indication that memory is tighter.
1239     */
1240    boolean mAllowLowerMemLevel = false;
1241
1242    /**
1243     * The last computed memory level, for holding when we are in a state that
1244     * processes are going away for other reasons.
1245     */
1246    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1247
1248    /**
1249     * The last total number of process we have, to determine if changes actually look
1250     * like a shrinking number of process due to lower RAM.
1251     */
1252    int mLastNumProcesses;
1253
1254    /**
1255     * The uptime of the last time we performed idle maintenance.
1256     */
1257    long mLastIdleTime = SystemClock.uptimeMillis();
1258
1259    /**
1260     * Total time spent with RAM that has been added in the past since the last idle time.
1261     */
1262    long mLowRamTimeSinceLastIdle = 0;
1263
1264    /**
1265     * If RAM is currently low, when that horrible situation started.
1266     */
1267    long mLowRamStartTime = 0;
1268
1269    /**
1270     * For reporting to battery stats the current top application.
1271     */
1272    private String mCurResumedPackage = null;
1273    private int mCurResumedUid = -1;
1274
1275    /**
1276     * For reporting to battery stats the apps currently running foreground
1277     * service.  The ProcessMap is package/uid tuples; each of these contain
1278     * an array of the currently foreground processes.
1279     */
1280    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1281            = new ProcessMap<ArrayList<ProcessRecord>>();
1282
1283    /**
1284     * This is set if we had to do a delayed dexopt of an app before launching
1285     * it, to increase the ANR timeouts in that case.
1286     */
1287    boolean mDidDexOpt;
1288
1289    /**
1290     * Set if the systemServer made a call to enterSafeMode.
1291     */
1292    boolean mSafeMode;
1293
1294    /**
1295     * If true, we are running under a test environment so will sample PSS from processes
1296     * much more rapidly to try to collect better data when the tests are rapidly
1297     * running through apps.
1298     */
1299    boolean mTestPssMode = false;
1300
1301    String mDebugApp = null;
1302    boolean mWaitForDebugger = false;
1303    boolean mDebugTransient = false;
1304    String mOrigDebugApp = null;
1305    boolean mOrigWaitForDebugger = false;
1306    boolean mAlwaysFinishActivities = false;
1307    boolean mLenientBackgroundCheck = false;
1308    boolean mForceResizableActivities;
1309    boolean mSupportsMultiWindow;
1310    boolean mSupportsFreeformWindowManagement;
1311    boolean mSupportsPictureInPicture;
1312    Rect mDefaultPinnedStackBounds;
1313    IActivityController mController = null;
1314    boolean mControllerIsAMonkey = false;
1315    String mProfileApp = null;
1316    ProcessRecord mProfileProc = null;
1317    String mProfileFile;
1318    ParcelFileDescriptor mProfileFd;
1319    int mSamplingInterval = 0;
1320    boolean mAutoStopProfiler = false;
1321    int mProfileType = 0;
1322    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1323    String mMemWatchDumpProcName;
1324    String mMemWatchDumpFile;
1325    int mMemWatchDumpPid;
1326    int mMemWatchDumpUid;
1327    String mTrackAllocationApp = null;
1328    String mNativeDebuggingApp = null;
1329
1330    final long[] mTmpLong = new long[2];
1331
1332    static final class ProcessChangeItem {
1333        static final int CHANGE_ACTIVITIES = 1<<0;
1334        static final int CHANGE_PROCESS_STATE = 1<<1;
1335        int changes;
1336        int uid;
1337        int pid;
1338        int processState;
1339        boolean foregroundActivities;
1340    }
1341
1342    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1343    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1344
1345    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1346    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1347
1348    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1349    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1350
1351    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1352    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1353
1354    /**
1355     * Runtime CPU use collection thread.  This object's lock is used to
1356     * perform synchronization with the thread (notifying it to run).
1357     */
1358    final Thread mProcessCpuThread;
1359
1360    /**
1361     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1362     * Must acquire this object's lock when accessing it.
1363     * NOTE: this lock will be held while doing long operations (trawling
1364     * through all processes in /proc), so it should never be acquired by
1365     * any critical paths such as when holding the main activity manager lock.
1366     */
1367    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1368            MONITOR_THREAD_CPU_USAGE);
1369    final AtomicLong mLastCpuTime = new AtomicLong(0);
1370    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1371
1372    long mLastWriteTime = 0;
1373
1374    /**
1375     * Used to retain an update lock when the foreground activity is in
1376     * immersive mode.
1377     */
1378    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1379
1380    /**
1381     * Set to true after the system has finished booting.
1382     */
1383    boolean mBooted = false;
1384
1385    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1386    int mProcessLimitOverride = -1;
1387
1388    WindowManagerService mWindowManager;
1389    final ActivityThread mSystemThread;
1390
1391    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1392        final ProcessRecord mApp;
1393        final int mPid;
1394        final IApplicationThread mAppThread;
1395
1396        AppDeathRecipient(ProcessRecord app, int pid,
1397                IApplicationThread thread) {
1398            if (DEBUG_ALL) Slog.v(
1399                TAG, "New death recipient " + this
1400                + " for thread " + thread.asBinder());
1401            mApp = app;
1402            mPid = pid;
1403            mAppThread = thread;
1404        }
1405
1406        @Override
1407        public void binderDied() {
1408            if (DEBUG_ALL) Slog.v(
1409                TAG, "Death received in " + this
1410                + " for thread " + mAppThread.asBinder());
1411            synchronized(ActivityManagerService.this) {
1412                appDiedLocked(mApp, mPid, mAppThread, true);
1413            }
1414        }
1415    }
1416
1417    static final int SHOW_ERROR_UI_MSG = 1;
1418    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1419    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1420    static final int UPDATE_CONFIGURATION_MSG = 4;
1421    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1422    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1423    static final int SERVICE_TIMEOUT_MSG = 12;
1424    static final int UPDATE_TIME_ZONE = 13;
1425    static final int SHOW_UID_ERROR_UI_MSG = 14;
1426    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1427    static final int PROC_START_TIMEOUT_MSG = 20;
1428    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1429    static final int KILL_APPLICATION_MSG = 22;
1430    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1431    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1432    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1433    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1434    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1435    static final int CLEAR_DNS_CACHE_MSG = 28;
1436    static final int UPDATE_HTTP_PROXY_MSG = 29;
1437    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1438    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1439    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1440    static final int REPORT_MEM_USAGE_MSG = 33;
1441    static final int REPORT_USER_SWITCH_MSG = 34;
1442    static final int CONTINUE_USER_SWITCH_MSG = 35;
1443    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1444    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1445    static final int PERSIST_URI_GRANTS_MSG = 38;
1446    static final int REQUEST_ALL_PSS_MSG = 39;
1447    static final int START_PROFILES_MSG = 40;
1448    static final int UPDATE_TIME = 41;
1449    static final int SYSTEM_USER_START_MSG = 42;
1450    static final int SYSTEM_USER_CURRENT_MSG = 43;
1451    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1452    static final int FINISH_BOOTING_MSG = 45;
1453    static final int START_USER_SWITCH_UI_MSG = 46;
1454    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1455    static final int DISMISS_DIALOG_UI_MSG = 48;
1456    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1457    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1458    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1459    static final int DELETE_DUMPHEAP_MSG = 52;
1460    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1461    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1462    static final int REPORT_TIME_TRACKER_MSG = 55;
1463    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1464    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1465    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1466    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1467    static final int IDLE_UIDS_MSG = 60;
1468    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1469    static final int LOG_STACK_STATE = 62;
1470    static final int VR_MODE_CHANGE_MSG = 63;
1471    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1472    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1473    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1474    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1475    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1476    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1477
1478    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1479    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1480    static final int FIRST_COMPAT_MODE_MSG = 300;
1481    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1482
1483    static ServiceThread sKillThread = null;
1484    static KillHandler sKillHandler = null;
1485
1486    CompatModeDialog mCompatModeDialog;
1487    long mLastMemUsageReportTime = 0;
1488
1489    /**
1490     * Flag whether the current user is a "monkey", i.e. whether
1491     * the UI is driven by a UI automation tool.
1492     */
1493    private boolean mUserIsMonkey;
1494
1495    /** Flag whether the device has a Recents UI */
1496    boolean mHasRecents;
1497
1498    /** The dimensions of the thumbnails in the Recents UI. */
1499    int mThumbnailWidth;
1500    int mThumbnailHeight;
1501    float mFullscreenThumbnailScale;
1502
1503    final ServiceThread mHandlerThread;
1504    final MainHandler mHandler;
1505    final UiHandler mUiHandler;
1506
1507    PackageManagerInternal mPackageManagerInt;
1508
1509    final class KillHandler extends Handler {
1510        static final int KILL_PROCESS_GROUP_MSG = 4000;
1511
1512        public KillHandler(Looper looper) {
1513            super(looper, null, true);
1514        }
1515
1516        @Override
1517        public void handleMessage(Message msg) {
1518            switch (msg.what) {
1519                case KILL_PROCESS_GROUP_MSG:
1520                {
1521                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1522                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1523                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1524                }
1525                break;
1526
1527                default:
1528                    super.handleMessage(msg);
1529            }
1530        }
1531    }
1532
1533    final class UiHandler extends Handler {
1534        public UiHandler() {
1535            super(com.android.server.UiThread.get().getLooper(), null, true);
1536        }
1537
1538        @Override
1539        public void handleMessage(Message msg) {
1540            switch (msg.what) {
1541            case SHOW_ERROR_UI_MSG: {
1542                mAppErrors.handleShowAppErrorUi(msg);
1543                ensureBootCompleted();
1544            } break;
1545            case SHOW_NOT_RESPONDING_UI_MSG: {
1546                mAppErrors.handleShowAnrUi(msg);
1547                ensureBootCompleted();
1548            } break;
1549            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1550                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1551                synchronized (ActivityManagerService.this) {
1552                    ProcessRecord proc = (ProcessRecord) data.get("app");
1553                    if (proc == null) {
1554                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1555                        break;
1556                    }
1557                    if (proc.crashDialog != null) {
1558                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1559                        return;
1560                    }
1561                    AppErrorResult res = (AppErrorResult) data.get("result");
1562                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1563                        Dialog d = new StrictModeViolationDialog(mContext,
1564                                ActivityManagerService.this, res, proc);
1565                        d.show();
1566                        proc.crashDialog = d;
1567                    } else {
1568                        // The device is asleep, so just pretend that the user
1569                        // saw a crash dialog and hit "force quit".
1570                        res.set(0);
1571                    }
1572                }
1573                ensureBootCompleted();
1574            } break;
1575            case SHOW_FACTORY_ERROR_UI_MSG: {
1576                Dialog d = new FactoryErrorDialog(
1577                    mContext, msg.getData().getCharSequence("msg"));
1578                d.show();
1579                ensureBootCompleted();
1580            } break;
1581            case WAIT_FOR_DEBUGGER_UI_MSG: {
1582                synchronized (ActivityManagerService.this) {
1583                    ProcessRecord app = (ProcessRecord)msg.obj;
1584                    if (msg.arg1 != 0) {
1585                        if (!app.waitedForDebugger) {
1586                            Dialog d = new AppWaitingForDebuggerDialog(
1587                                    ActivityManagerService.this,
1588                                    mContext, app);
1589                            app.waitDialog = d;
1590                            app.waitedForDebugger = true;
1591                            d.show();
1592                        }
1593                    } else {
1594                        if (app.waitDialog != null) {
1595                            app.waitDialog.dismiss();
1596                            app.waitDialog = null;
1597                        }
1598                    }
1599                }
1600            } break;
1601            case SHOW_UID_ERROR_UI_MSG: {
1602                if (mShowDialogs) {
1603                    AlertDialog d = new BaseErrorDialog(mContext);
1604                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1605                    d.setCancelable(false);
1606                    d.setTitle(mContext.getText(R.string.android_system_label));
1607                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1608                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1609                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1610                    d.show();
1611                }
1612            } break;
1613            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1614                if (mShowDialogs) {
1615                    AlertDialog d = new BaseErrorDialog(mContext);
1616                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1617                    d.setCancelable(false);
1618                    d.setTitle(mContext.getText(R.string.android_system_label));
1619                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1620                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1621                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1622                    d.show();
1623                }
1624            } break;
1625            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1626                synchronized (ActivityManagerService.this) {
1627                    ActivityRecord ar = (ActivityRecord) msg.obj;
1628                    if (mCompatModeDialog != null) {
1629                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1630                                ar.info.applicationInfo.packageName)) {
1631                            return;
1632                        }
1633                        mCompatModeDialog.dismiss();
1634                        mCompatModeDialog = null;
1635                    }
1636                    if (ar != null && false) {
1637                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1638                                ar.packageName)) {
1639                            int mode = mCompatModePackages.computeCompatModeLocked(
1640                                    ar.info.applicationInfo);
1641                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1642                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1643                                mCompatModeDialog = new CompatModeDialog(
1644                                        ActivityManagerService.this, mContext,
1645                                        ar.info.applicationInfo);
1646                                mCompatModeDialog.show();
1647                            }
1648                        }
1649                    }
1650                }
1651                break;
1652            }
1653            case START_USER_SWITCH_UI_MSG: {
1654                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1655                break;
1656            }
1657            case DISMISS_DIALOG_UI_MSG: {
1658                final Dialog d = (Dialog) msg.obj;
1659                d.dismiss();
1660                break;
1661            }
1662            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1663                dispatchProcessesChanged();
1664                break;
1665            }
1666            case DISPATCH_PROCESS_DIED_UI_MSG: {
1667                final int pid = msg.arg1;
1668                final int uid = msg.arg2;
1669                dispatchProcessDied(pid, uid);
1670                break;
1671            }
1672            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1673                dispatchUidsChanged();
1674            } break;
1675            }
1676        }
1677    }
1678
1679    final class MainHandler extends Handler {
1680        public MainHandler(Looper looper) {
1681            super(looper, null, true);
1682        }
1683
1684        @Override
1685        public void handleMessage(Message msg) {
1686            switch (msg.what) {
1687            case UPDATE_CONFIGURATION_MSG: {
1688                final ContentResolver resolver = mContext.getContentResolver();
1689                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1690                        msg.arg1);
1691            } break;
1692            case GC_BACKGROUND_PROCESSES_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    performAppGcsIfAppropriateLocked();
1695                }
1696            } break;
1697            case SERVICE_TIMEOUT_MSG: {
1698                if (mDidDexOpt) {
1699                    mDidDexOpt = false;
1700                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1701                    nmsg.obj = msg.obj;
1702                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1703                    return;
1704                }
1705                mServices.serviceTimeout((ProcessRecord)msg.obj);
1706            } break;
1707            case UPDATE_TIME_ZONE: {
1708                synchronized (ActivityManagerService.this) {
1709                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1710                        ProcessRecord r = mLruProcesses.get(i);
1711                        if (r.thread != null) {
1712                            try {
1713                                r.thread.updateTimeZone();
1714                            } catch (RemoteException ex) {
1715                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1716                            }
1717                        }
1718                    }
1719                }
1720            } break;
1721            case CLEAR_DNS_CACHE_MSG: {
1722                synchronized (ActivityManagerService.this) {
1723                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1724                        ProcessRecord r = mLruProcesses.get(i);
1725                        if (r.thread != null) {
1726                            try {
1727                                r.thread.clearDnsCache();
1728                            } catch (RemoteException ex) {
1729                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1730                            }
1731                        }
1732                    }
1733                }
1734            } break;
1735            case UPDATE_HTTP_PROXY_MSG: {
1736                ProxyInfo proxy = (ProxyInfo)msg.obj;
1737                String host = "";
1738                String port = "";
1739                String exclList = "";
1740                Uri pacFileUrl = Uri.EMPTY;
1741                if (proxy != null) {
1742                    host = proxy.getHost();
1743                    port = Integer.toString(proxy.getPort());
1744                    exclList = proxy.getExclusionListAsString();
1745                    pacFileUrl = proxy.getPacFileUrl();
1746                }
1747                synchronized (ActivityManagerService.this) {
1748                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1749                        ProcessRecord r = mLruProcesses.get(i);
1750                        if (r.thread != null) {
1751                            try {
1752                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1753                            } catch (RemoteException ex) {
1754                                Slog.w(TAG, "Failed to update http proxy for: " +
1755                                        r.info.processName);
1756                            }
1757                        }
1758                    }
1759                }
1760            } break;
1761            case PROC_START_TIMEOUT_MSG: {
1762                if (mDidDexOpt) {
1763                    mDidDexOpt = false;
1764                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1765                    nmsg.obj = msg.obj;
1766                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1767                    return;
1768                }
1769                ProcessRecord app = (ProcessRecord)msg.obj;
1770                synchronized (ActivityManagerService.this) {
1771                    processStartTimedOutLocked(app);
1772                }
1773            } break;
1774            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1775                ProcessRecord app = (ProcessRecord)msg.obj;
1776                synchronized (ActivityManagerService.this) {
1777                    processContentProviderPublishTimedOutLocked(app);
1778                }
1779            } break;
1780            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1783                }
1784            } break;
1785            case KILL_APPLICATION_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    int appid = msg.arg1;
1788                    boolean restart = (msg.arg2 == 1);
1789                    Bundle bundle = (Bundle)msg.obj;
1790                    String pkg = bundle.getString("pkg");
1791                    String reason = bundle.getString("reason");
1792                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1793                            false, UserHandle.USER_ALL, reason);
1794                }
1795            } break;
1796            case FINALIZE_PENDING_INTENT_MSG: {
1797                ((PendingIntentRecord)msg.obj).completeFinalize();
1798            } break;
1799            case POST_HEAVY_NOTIFICATION_MSG: {
1800                INotificationManager inm = NotificationManager.getService();
1801                if (inm == null) {
1802                    return;
1803                }
1804
1805                ActivityRecord root = (ActivityRecord)msg.obj;
1806                ProcessRecord process = root.app;
1807                if (process == null) {
1808                    return;
1809                }
1810
1811                try {
1812                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1813                    String text = mContext.getString(R.string.heavy_weight_notification,
1814                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1815                    Notification notification = new Notification.Builder(context)
1816                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1817                            .setWhen(0)
1818                            .setOngoing(true)
1819                            .setTicker(text)
1820                            .setColor(mContext.getColor(
1821                                    com.android.internal.R.color.system_notification_accent_color))
1822                            .setContentTitle(text)
1823                            .setContentText(
1824                                    mContext.getText(R.string.heavy_weight_notification_detail))
1825                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1826                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1827                                    new UserHandle(root.userId)))
1828                            .build();
1829                    try {
1830                        int[] outId = new int[1];
1831                        inm.enqueueNotificationWithTag("android", "android", null,
1832                                R.string.heavy_weight_notification,
1833                                notification, outId, root.userId);
1834                    } catch (RuntimeException e) {
1835                        Slog.w(ActivityManagerService.TAG,
1836                                "Error showing notification for heavy-weight app", e);
1837                    } catch (RemoteException e) {
1838                    }
1839                } catch (NameNotFoundException e) {
1840                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1841                }
1842            } break;
1843            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1844                INotificationManager inm = NotificationManager.getService();
1845                if (inm == null) {
1846                    return;
1847                }
1848                try {
1849                    inm.cancelNotificationWithTag("android", null,
1850                            R.string.heavy_weight_notification,  msg.arg1);
1851                } catch (RuntimeException e) {
1852                    Slog.w(ActivityManagerService.TAG,
1853                            "Error canceling notification for service", e);
1854                } catch (RemoteException e) {
1855                }
1856            } break;
1857            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1858                synchronized (ActivityManagerService.this) {
1859                    checkExcessivePowerUsageLocked(true);
1860                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1861                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1862                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1863                }
1864            } break;
1865            case REPORT_MEM_USAGE_MSG: {
1866                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1867                Thread thread = new Thread() {
1868                    @Override public void run() {
1869                        reportMemUsage(memInfos);
1870                    }
1871                };
1872                thread.start();
1873                break;
1874            }
1875            case REPORT_USER_SWITCH_MSG: {
1876                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1877                break;
1878            }
1879            case CONTINUE_USER_SWITCH_MSG: {
1880                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1881                break;
1882            }
1883            case USER_SWITCH_TIMEOUT_MSG: {
1884                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1885                break;
1886            }
1887            case IMMERSIVE_MODE_LOCK_MSG: {
1888                final boolean nextState = (msg.arg1 != 0);
1889                if (mUpdateLock.isHeld() != nextState) {
1890                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1891                            "Applying new update lock state '" + nextState
1892                            + "' for " + (ActivityRecord)msg.obj);
1893                    if (nextState) {
1894                        mUpdateLock.acquire();
1895                    } else {
1896                        mUpdateLock.release();
1897                    }
1898                }
1899                break;
1900            }
1901            case PERSIST_URI_GRANTS_MSG: {
1902                writeGrantedUriPermissions();
1903                break;
1904            }
1905            case REQUEST_ALL_PSS_MSG: {
1906                synchronized (ActivityManagerService.this) {
1907                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1908                }
1909                break;
1910            }
1911            case START_PROFILES_MSG: {
1912                synchronized (ActivityManagerService.this) {
1913                    mUserController.startProfilesLocked();
1914                }
1915                break;
1916            }
1917            case UPDATE_TIME: {
1918                synchronized (ActivityManagerService.this) {
1919                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1920                        ProcessRecord r = mLruProcesses.get(i);
1921                        if (r.thread != null) {
1922                            try {
1923                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1924                            } catch (RemoteException ex) {
1925                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1926                            }
1927                        }
1928                    }
1929                }
1930                break;
1931            }
1932            case SYSTEM_USER_START_MSG: {
1933                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1934                        Integer.toString(msg.arg1), msg.arg1);
1935                mSystemServiceManager.startUser(msg.arg1);
1936                break;
1937            }
1938            case SYSTEM_USER_UNLOCK_MSG: {
1939                final int userId = msg.arg1;
1940                mSystemServiceManager.unlockUser(userId);
1941                synchronized (ActivityManagerService.this) {
1942                    mRecentTasks.loadUserRecentsLocked(userId);
1943                }
1944                if (userId == UserHandle.USER_SYSTEM) {
1945                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1946                }
1947                installEncryptionUnawareProviders(userId);
1948                break;
1949            }
1950            case SYSTEM_USER_CURRENT_MSG: {
1951                mBatteryStatsService.noteEvent(
1952                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1953                        Integer.toString(msg.arg2), msg.arg2);
1954                mBatteryStatsService.noteEvent(
1955                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1956                        Integer.toString(msg.arg1), msg.arg1);
1957                mSystemServiceManager.switchUser(msg.arg1);
1958                break;
1959            }
1960            case ENTER_ANIMATION_COMPLETE_MSG: {
1961                synchronized (ActivityManagerService.this) {
1962                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1963                    if (r != null && r.app != null && r.app.thread != null) {
1964                        try {
1965                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1966                        } catch (RemoteException e) {
1967                        }
1968                    }
1969                }
1970                break;
1971            }
1972            case FINISH_BOOTING_MSG: {
1973                if (msg.arg1 != 0) {
1974                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1975                    finishBooting();
1976                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1977                }
1978                if (msg.arg2 != 0) {
1979                    enableScreenAfterBoot();
1980                }
1981                break;
1982            }
1983            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1984                try {
1985                    Locale l = (Locale) msg.obj;
1986                    IBinder service = ServiceManager.getService("mount");
1987                    IMountService mountService = IMountService.Stub.asInterface(service);
1988                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1989                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1990                } catch (RemoteException e) {
1991                    Log.e(TAG, "Error storing locale for decryption UI", e);
1992                }
1993                break;
1994            }
1995            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1996                synchronized (ActivityManagerService.this) {
1997                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1998                        try {
1999                            // Make a one-way callback to the listener
2000                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2001                        } catch (RemoteException e){
2002                            // Handled by the RemoteCallbackList
2003                        }
2004                    }
2005                    mTaskStackListeners.finishBroadcast();
2006                }
2007                break;
2008            }
2009            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2010                synchronized (ActivityManagerService.this) {
2011                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2012                        try {
2013                            // Make a one-way callback to the listener
2014                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2015                        } catch (RemoteException e){
2016                            // Handled by the RemoteCallbackList
2017                        }
2018                    }
2019                    mTaskStackListeners.finishBroadcast();
2020                }
2021                break;
2022            }
2023            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2024                synchronized (ActivityManagerService.this) {
2025                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2026                        try {
2027                            // Make a one-way callback to the listener
2028                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2029                        } catch (RemoteException e){
2030                            // Handled by the RemoteCallbackList
2031                        }
2032                    }
2033                    mTaskStackListeners.finishBroadcast();
2034                }
2035                break;
2036            }
2037            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2038                synchronized (ActivityManagerService.this) {
2039                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2040                        try {
2041                            // Make a one-way callback to the listener
2042                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2043                        } catch (RemoteException e){
2044                            // Handled by the RemoteCallbackList
2045                        }
2046                    }
2047                    mTaskStackListeners.finishBroadcast();
2048                }
2049                break;
2050            }
2051            case NOTIFY_FORCED_RESIZABLE_MSG: {
2052                synchronized (ActivityManagerService.this) {
2053                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2054                        try {
2055                            // Make a one-way callback to the listener
2056                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2057                                    (String) msg.obj, msg.arg1);
2058                        } catch (RemoteException e){
2059                            // Handled by the RemoteCallbackList
2060                        }
2061                    }
2062                    mTaskStackListeners.finishBroadcast();
2063                }
2064                break;
2065            }
2066                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2067                    synchronized (ActivityManagerService.this) {
2068                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2069                            try {
2070                                // Make a one-way callback to the listener
2071                                mTaskStackListeners.getBroadcastItem(i)
2072                                        .onActivityDismissingDockedStack();
2073                            } catch (RemoteException e){
2074                                // Handled by the RemoteCallbackList
2075                            }
2076                        }
2077                        mTaskStackListeners.finishBroadcast();
2078                    }
2079                    break;
2080                }
2081            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2082                final int uid = msg.arg1;
2083                final byte[] firstPacket = (byte[]) msg.obj;
2084
2085                synchronized (mPidsSelfLocked) {
2086                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2087                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2088                        if (p.uid == uid) {
2089                            try {
2090                                p.thread.notifyCleartextNetwork(firstPacket);
2091                            } catch (RemoteException ignored) {
2092                            }
2093                        }
2094                    }
2095                }
2096                break;
2097            }
2098            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2099                final String procName;
2100                final int uid;
2101                final long memLimit;
2102                final String reportPackage;
2103                synchronized (ActivityManagerService.this) {
2104                    procName = mMemWatchDumpProcName;
2105                    uid = mMemWatchDumpUid;
2106                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2107                    if (val == null) {
2108                        val = mMemWatchProcesses.get(procName, 0);
2109                    }
2110                    if (val != null) {
2111                        memLimit = val.first;
2112                        reportPackage = val.second;
2113                    } else {
2114                        memLimit = 0;
2115                        reportPackage = null;
2116                    }
2117                }
2118                if (procName == null) {
2119                    return;
2120                }
2121
2122                if (DEBUG_PSS) Slog.d(TAG_PSS,
2123                        "Showing dump heap notification from " + procName + "/" + uid);
2124
2125                INotificationManager inm = NotificationManager.getService();
2126                if (inm == null) {
2127                    return;
2128                }
2129
2130                String text = mContext.getString(R.string.dump_heap_notification, procName);
2131
2132
2133                Intent deleteIntent = new Intent();
2134                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2135                Intent intent = new Intent();
2136                intent.setClassName("android", DumpHeapActivity.class.getName());
2137                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2138                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2139                if (reportPackage != null) {
2140                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2141                }
2142                int userId = UserHandle.getUserId(uid);
2143                Notification notification = new Notification.Builder(mContext)
2144                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2145                        .setWhen(0)
2146                        .setOngoing(true)
2147                        .setAutoCancel(true)
2148                        .setTicker(text)
2149                        .setColor(mContext.getColor(
2150                                com.android.internal.R.color.system_notification_accent_color))
2151                        .setContentTitle(text)
2152                        .setContentText(
2153                                mContext.getText(R.string.dump_heap_notification_detail))
2154                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2155                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2156                                new UserHandle(userId)))
2157                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2158                                deleteIntent, 0, UserHandle.SYSTEM))
2159                        .build();
2160
2161                try {
2162                    int[] outId = new int[1];
2163                    inm.enqueueNotificationWithTag("android", "android", null,
2164                            R.string.dump_heap_notification,
2165                            notification, outId, userId);
2166                } catch (RuntimeException e) {
2167                    Slog.w(ActivityManagerService.TAG,
2168                            "Error showing notification for dump heap", e);
2169                } catch (RemoteException e) {
2170                }
2171            } break;
2172            case DELETE_DUMPHEAP_MSG: {
2173                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2174                        DumpHeapActivity.JAVA_URI,
2175                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2176                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2177                        UserHandle.myUserId());
2178                synchronized (ActivityManagerService.this) {
2179                    mMemWatchDumpFile = null;
2180                    mMemWatchDumpProcName = null;
2181                    mMemWatchDumpPid = -1;
2182                    mMemWatchDumpUid = -1;
2183                }
2184            } break;
2185            case FOREGROUND_PROFILE_CHANGED_MSG: {
2186                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2187            } break;
2188            case REPORT_TIME_TRACKER_MSG: {
2189                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2190                tracker.deliverResult(mContext);
2191            } break;
2192            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2193                mUserController.dispatchUserSwitchComplete(msg.arg1);
2194            } break;
2195            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2196                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2197                try {
2198                    connection.shutdown();
2199                } catch (RemoteException e) {
2200                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2201                }
2202                // Only a UiAutomation can set this flag and now that
2203                // it is finished we make sure it is reset to its default.
2204                mUserIsMonkey = false;
2205            } break;
2206            case APP_BOOST_DEACTIVATE_MSG: {
2207                synchronized(ActivityManagerService.this) {
2208                    if (mIsBoosted) {
2209                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2210                            nativeMigrateFromBoost();
2211                            mIsBoosted = false;
2212                            mBoostStartTime = 0;
2213                        } else {
2214                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2215                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2216                        }
2217                    }
2218                }
2219            } break;
2220            case IDLE_UIDS_MSG: {
2221                idleUids();
2222            } break;
2223            case LOG_STACK_STATE: {
2224                synchronized (ActivityManagerService.this) {
2225                    mStackSupervisor.logStackState();
2226                }
2227            } break;
2228            case VR_MODE_CHANGE_MSG: {
2229                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2230                final ActivityRecord r = (ActivityRecord) msg.obj;
2231                boolean vrMode;
2232                ComponentName requestedPackage;
2233                ComponentName callingPackage;
2234                int userId;
2235                synchronized (ActivityManagerService.this) {
2236                    vrMode = r.requestedVrComponent != null;
2237                    requestedPackage = r.requestedVrComponent;
2238                    userId = r.userId;
2239                    callingPackage = r.info.getComponentName();
2240                    if (mInVrMode != vrMode) {
2241                        mInVrMode = vrMode;
2242                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2243                    }
2244                }
2245                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2246            } break;
2247            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2248                final ActivityRecord r = (ActivityRecord) msg.obj;
2249                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2250                if (needsVrMode) {
2251                    VrManagerInternal vrService =
2252                            LocalServices.getService(VrManagerInternal.class);
2253                    boolean enable = msg.arg1 == 1;
2254                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2255                            r.info.getComponentName());
2256                }
2257            } break;
2258            }
2259        }
2260    };
2261
2262    static final int COLLECT_PSS_BG_MSG = 1;
2263
2264    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2265        @Override
2266        public void handleMessage(Message msg) {
2267            switch (msg.what) {
2268            case COLLECT_PSS_BG_MSG: {
2269                long start = SystemClock.uptimeMillis();
2270                MemInfoReader memInfo = null;
2271                synchronized (ActivityManagerService.this) {
2272                    if (mFullPssPending) {
2273                        mFullPssPending = false;
2274                        memInfo = new MemInfoReader();
2275                    }
2276                }
2277                if (memInfo != null) {
2278                    updateCpuStatsNow();
2279                    long nativeTotalPss = 0;
2280                    synchronized (mProcessCpuTracker) {
2281                        final int N = mProcessCpuTracker.countStats();
2282                        for (int j=0; j<N; j++) {
2283                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2284                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2285                                // This is definitely an application process; skip it.
2286                                continue;
2287                            }
2288                            synchronized (mPidsSelfLocked) {
2289                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2290                                    // This is one of our own processes; skip it.
2291                                    continue;
2292                                }
2293                            }
2294                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2295                        }
2296                    }
2297                    memInfo.readMemInfo();
2298                    synchronized (ActivityManagerService.this) {
2299                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2300                                + (SystemClock.uptimeMillis()-start) + "ms");
2301                        final long cachedKb = memInfo.getCachedSizeKb();
2302                        final long freeKb = memInfo.getFreeSizeKb();
2303                        final long zramKb = memInfo.getZramTotalSizeKb();
2304                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2305                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2306                                kernelKb*1024, nativeTotalPss*1024);
2307                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2308                                nativeTotalPss);
2309                    }
2310                }
2311
2312                int num = 0;
2313                long[] tmp = new long[2];
2314                do {
2315                    ProcessRecord proc;
2316                    int procState;
2317                    int pid;
2318                    long lastPssTime;
2319                    synchronized (ActivityManagerService.this) {
2320                        if (mPendingPssProcesses.size() <= 0) {
2321                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2322                                    "Collected PSS of " + num + " processes in "
2323                                    + (SystemClock.uptimeMillis() - start) + "ms");
2324                            mPendingPssProcesses.clear();
2325                            return;
2326                        }
2327                        proc = mPendingPssProcesses.remove(0);
2328                        procState = proc.pssProcState;
2329                        lastPssTime = proc.lastPssTime;
2330                        if (proc.thread != null && procState == proc.setProcState
2331                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2332                                        < SystemClock.uptimeMillis()) {
2333                            pid = proc.pid;
2334                        } else {
2335                            proc = null;
2336                            pid = 0;
2337                        }
2338                    }
2339                    if (proc != null) {
2340                        long pss = Debug.getPss(pid, tmp, null);
2341                        synchronized (ActivityManagerService.this) {
2342                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2343                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2344                                num++;
2345                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2346                                        SystemClock.uptimeMillis());
2347                            }
2348                        }
2349                    }
2350                } while (true);
2351            }
2352            }
2353        }
2354    };
2355
2356    public void setSystemProcess() {
2357        try {
2358            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2359            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2360            ServiceManager.addService("meminfo", new MemBinder(this));
2361            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2362            ServiceManager.addService("dbinfo", new DbBinder(this));
2363            if (MONITOR_CPU_USAGE) {
2364                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2365            }
2366            ServiceManager.addService("permission", new PermissionController(this));
2367            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2368
2369            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2370                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2371            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2372
2373            synchronized (this) {
2374                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2375                app.persistent = true;
2376                app.pid = MY_PID;
2377                app.maxAdj = ProcessList.SYSTEM_ADJ;
2378                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2379                synchronized (mPidsSelfLocked) {
2380                    mPidsSelfLocked.put(app.pid, app);
2381                }
2382                updateLruProcessLocked(app, false, null);
2383                updateOomAdjLocked();
2384            }
2385        } catch (PackageManager.NameNotFoundException e) {
2386            throw new RuntimeException(
2387                    "Unable to find android system package", e);
2388        }
2389    }
2390
2391    public void setWindowManager(WindowManagerService wm) {
2392        mWindowManager = wm;
2393        mStackSupervisor.setWindowManager(wm);
2394        mActivityStarter.setWindowManager(wm);
2395    }
2396
2397    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2398        mUsageStatsService = usageStatsManager;
2399    }
2400
2401    public void startObservingNativeCrashes() {
2402        final NativeCrashListener ncl = new NativeCrashListener(this);
2403        ncl.start();
2404    }
2405
2406    public IAppOpsService getAppOpsService() {
2407        return mAppOpsService;
2408    }
2409
2410    static class MemBinder extends Binder {
2411        ActivityManagerService mActivityManagerService;
2412        MemBinder(ActivityManagerService activityManagerService) {
2413            mActivityManagerService = activityManagerService;
2414        }
2415
2416        @Override
2417        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2418            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2419                    != PackageManager.PERMISSION_GRANTED) {
2420                pw.println("Permission Denial: can't dump meminfo from from pid="
2421                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2422                        + " without permission " + android.Manifest.permission.DUMP);
2423                return;
2424            }
2425
2426            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2427        }
2428    }
2429
2430    static class GraphicsBinder extends Binder {
2431        ActivityManagerService mActivityManagerService;
2432        GraphicsBinder(ActivityManagerService activityManagerService) {
2433            mActivityManagerService = activityManagerService;
2434        }
2435
2436        @Override
2437        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2438            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2439                    != PackageManager.PERMISSION_GRANTED) {
2440                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2441                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2442                        + " without permission " + android.Manifest.permission.DUMP);
2443                return;
2444            }
2445
2446            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2447        }
2448    }
2449
2450    static class DbBinder extends Binder {
2451        ActivityManagerService mActivityManagerService;
2452        DbBinder(ActivityManagerService activityManagerService) {
2453            mActivityManagerService = activityManagerService;
2454        }
2455
2456        @Override
2457        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2458            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2459                    != PackageManager.PERMISSION_GRANTED) {
2460                pw.println("Permission Denial: can't dump dbinfo from from pid="
2461                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2462                        + " without permission " + android.Manifest.permission.DUMP);
2463                return;
2464            }
2465
2466            mActivityManagerService.dumpDbInfo(fd, pw, args);
2467        }
2468    }
2469
2470    static class CpuBinder extends Binder {
2471        ActivityManagerService mActivityManagerService;
2472        CpuBinder(ActivityManagerService activityManagerService) {
2473            mActivityManagerService = activityManagerService;
2474        }
2475
2476        @Override
2477        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2478            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2479                    != PackageManager.PERMISSION_GRANTED) {
2480                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2481                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2482                        + " without permission " + android.Manifest.permission.DUMP);
2483                return;
2484            }
2485
2486            synchronized (mActivityManagerService.mProcessCpuTracker) {
2487                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2488                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2489                        SystemClock.uptimeMillis()));
2490            }
2491        }
2492    }
2493
2494    public static final class Lifecycle extends SystemService {
2495        private final ActivityManagerService mService;
2496
2497        public Lifecycle(Context context) {
2498            super(context);
2499            mService = new ActivityManagerService(context);
2500        }
2501
2502        @Override
2503        public void onStart() {
2504            mService.start();
2505        }
2506
2507        public ActivityManagerService getService() {
2508            return mService;
2509        }
2510    }
2511
2512    // Note: This method is invoked on the main thread but may need to attach various
2513    // handlers to other threads.  So take care to be explicit about the looper.
2514    public ActivityManagerService(Context systemContext) {
2515        mContext = systemContext;
2516        mFactoryTest = FactoryTest.getMode();
2517        mSystemThread = ActivityThread.currentActivityThread();
2518
2519        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2520
2521        mHandlerThread = new ServiceThread(TAG,
2522                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2523        mHandlerThread.start();
2524        mHandler = new MainHandler(mHandlerThread.getLooper());
2525        mUiHandler = new UiHandler();
2526
2527        /* static; one-time init here */
2528        if (sKillHandler == null) {
2529            sKillThread = new ServiceThread(TAG + ":kill",
2530                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2531            sKillThread.start();
2532            sKillHandler = new KillHandler(sKillThread.getLooper());
2533        }
2534
2535        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2536                "foreground", BROADCAST_FG_TIMEOUT, false);
2537        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2538                "background", BROADCAST_BG_TIMEOUT, true);
2539        mBroadcastQueues[0] = mFgBroadcastQueue;
2540        mBroadcastQueues[1] = mBgBroadcastQueue;
2541
2542        mServices = new ActiveServices(this);
2543        mProviderMap = new ProviderMap(this);
2544        mAppErrors = new AppErrors(mContext, this);
2545
2546        // TODO: Move creation of battery stats service outside of activity manager service.
2547        File dataDir = Environment.getDataDirectory();
2548        File systemDir = new File(dataDir, "system");
2549        systemDir.mkdirs();
2550        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2551        mBatteryStatsService.getActiveStatistics().readLocked();
2552        mBatteryStatsService.scheduleWriteToDisk();
2553        mOnBattery = DEBUG_POWER ? true
2554                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2555        mBatteryStatsService.getActiveStatistics().setCallback(this);
2556
2557        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2558
2559        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2560        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2561                new IAppOpsCallback.Stub() {
2562                    @Override public void opChanged(int op, int uid, String packageName) {
2563                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2564                            if (mAppOpsService.checkOperation(op, uid, packageName)
2565                                    != AppOpsManager.MODE_ALLOWED) {
2566                                runInBackgroundDisabled(uid);
2567                            }
2568                        }
2569                    }
2570                });
2571
2572        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2573
2574        mUserController = new UserController(this);
2575
2576        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2577            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2578
2579        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2580
2581        mConfiguration.setToDefaults();
2582        mConfiguration.setLocales(LocaleList.getDefault());
2583
2584        mConfigurationSeq = mConfiguration.seq = 1;
2585        mProcessCpuTracker.init();
2586
2587        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2588        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2589        mStackSupervisor = new ActivityStackSupervisor(this);
2590        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2591        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2592
2593        mProcessCpuThread = new Thread("CpuTracker") {
2594            @Override
2595            public void run() {
2596                while (true) {
2597                    try {
2598                        try {
2599                            synchronized(this) {
2600                                final long now = SystemClock.uptimeMillis();
2601                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2602                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2603                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2604                                //        + ", write delay=" + nextWriteDelay);
2605                                if (nextWriteDelay < nextCpuDelay) {
2606                                    nextCpuDelay = nextWriteDelay;
2607                                }
2608                                if (nextCpuDelay > 0) {
2609                                    mProcessCpuMutexFree.set(true);
2610                                    this.wait(nextCpuDelay);
2611                                }
2612                            }
2613                        } catch (InterruptedException e) {
2614                        }
2615                        updateCpuStatsNow();
2616                    } catch (Exception e) {
2617                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2618                    }
2619                }
2620            }
2621        };
2622
2623        Watchdog.getInstance().addMonitor(this);
2624        Watchdog.getInstance().addThread(mHandler);
2625    }
2626
2627    public void setSystemServiceManager(SystemServiceManager mgr) {
2628        mSystemServiceManager = mgr;
2629    }
2630
2631    public void setInstaller(Installer installer) {
2632        mInstaller = installer;
2633    }
2634
2635    private void start() {
2636        Process.removeAllProcessGroups();
2637        mProcessCpuThread.start();
2638
2639        mBatteryStatsService.publish(mContext);
2640        mAppOpsService.publish(mContext);
2641        Slog.d("AppOps", "AppOpsService published");
2642        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2643    }
2644
2645    void onUserStoppedLocked(int userId) {
2646        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2647    }
2648
2649    public void initPowerManagement() {
2650        mStackSupervisor.initPowerManagement();
2651        mBatteryStatsService.initPowerManagement();
2652        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2653        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2654        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2655        mVoiceWakeLock.setReferenceCounted(false);
2656    }
2657
2658    @Override
2659    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2660            throws RemoteException {
2661        if (code == SYSPROPS_TRANSACTION) {
2662            // We need to tell all apps about the system property change.
2663            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2664            synchronized(this) {
2665                final int NP = mProcessNames.getMap().size();
2666                for (int ip=0; ip<NP; ip++) {
2667                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2668                    final int NA = apps.size();
2669                    for (int ia=0; ia<NA; ia++) {
2670                        ProcessRecord app = apps.valueAt(ia);
2671                        if (app.thread != null) {
2672                            procs.add(app.thread.asBinder());
2673                        }
2674                    }
2675                }
2676            }
2677
2678            int N = procs.size();
2679            for (int i=0; i<N; i++) {
2680                Parcel data2 = Parcel.obtain();
2681                try {
2682                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2683                } catch (RemoteException e) {
2684                }
2685                data2.recycle();
2686            }
2687        }
2688        try {
2689            return super.onTransact(code, data, reply, flags);
2690        } catch (RuntimeException e) {
2691            // The activity manager only throws security exceptions, so let's
2692            // log all others.
2693            if (!(e instanceof SecurityException)) {
2694                Slog.wtf(TAG, "Activity Manager Crash", e);
2695            }
2696            throw e;
2697        }
2698    }
2699
2700    void updateCpuStats() {
2701        final long now = SystemClock.uptimeMillis();
2702        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2703            return;
2704        }
2705        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2706            synchronized (mProcessCpuThread) {
2707                mProcessCpuThread.notify();
2708            }
2709        }
2710    }
2711
2712    void updateCpuStatsNow() {
2713        synchronized (mProcessCpuTracker) {
2714            mProcessCpuMutexFree.set(false);
2715            final long now = SystemClock.uptimeMillis();
2716            boolean haveNewCpuStats = false;
2717
2718            if (MONITOR_CPU_USAGE &&
2719                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2720                mLastCpuTime.set(now);
2721                mProcessCpuTracker.update();
2722                if (mProcessCpuTracker.hasGoodLastStats()) {
2723                    haveNewCpuStats = true;
2724                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2725                    //Slog.i(TAG, "Total CPU usage: "
2726                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2727
2728                    // Slog the cpu usage if the property is set.
2729                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2730                        int user = mProcessCpuTracker.getLastUserTime();
2731                        int system = mProcessCpuTracker.getLastSystemTime();
2732                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2733                        int irq = mProcessCpuTracker.getLastIrqTime();
2734                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2735                        int idle = mProcessCpuTracker.getLastIdleTime();
2736
2737                        int total = user + system + iowait + irq + softIrq + idle;
2738                        if (total == 0) total = 1;
2739
2740                        EventLog.writeEvent(EventLogTags.CPU,
2741                                ((user+system+iowait+irq+softIrq) * 100) / total,
2742                                (user * 100) / total,
2743                                (system * 100) / total,
2744                                (iowait * 100) / total,
2745                                (irq * 100) / total,
2746                                (softIrq * 100) / total);
2747                    }
2748                }
2749            }
2750
2751            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2752            synchronized(bstats) {
2753                synchronized(mPidsSelfLocked) {
2754                    if (haveNewCpuStats) {
2755                        if (bstats.startAddingCpuLocked()) {
2756                            int totalUTime = 0;
2757                            int totalSTime = 0;
2758                            final int N = mProcessCpuTracker.countStats();
2759                            for (int i=0; i<N; i++) {
2760                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2761                                if (!st.working) {
2762                                    continue;
2763                                }
2764                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2765                                totalUTime += st.rel_utime;
2766                                totalSTime += st.rel_stime;
2767                                if (pr != null) {
2768                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2769                                    if (ps == null || !ps.isActive()) {
2770                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2771                                                pr.info.uid, pr.processName);
2772                                    }
2773                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2774                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2775                                } else {
2776                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2777                                    if (ps == null || !ps.isActive()) {
2778                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2779                                                bstats.mapUid(st.uid), st.name);
2780                                    }
2781                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2782                                }
2783                            }
2784                            final int userTime = mProcessCpuTracker.getLastUserTime();
2785                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2786                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2787                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2788                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2789                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2790                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2791                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2792                        }
2793                    }
2794                }
2795
2796                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2797                    mLastWriteTime = now;
2798                    mBatteryStatsService.scheduleWriteToDisk();
2799                }
2800            }
2801        }
2802    }
2803
2804    @Override
2805    public void batteryNeedsCpuUpdate() {
2806        updateCpuStatsNow();
2807    }
2808
2809    @Override
2810    public void batteryPowerChanged(boolean onBattery) {
2811        // When plugging in, update the CPU stats first before changing
2812        // the plug state.
2813        updateCpuStatsNow();
2814        synchronized (this) {
2815            synchronized(mPidsSelfLocked) {
2816                mOnBattery = DEBUG_POWER ? true : onBattery;
2817            }
2818        }
2819    }
2820
2821    @Override
2822    public void batterySendBroadcast(Intent intent) {
2823        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2824                AppOpsManager.OP_NONE, null, false, false,
2825                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2826    }
2827
2828    /**
2829     * Initialize the application bind args. These are passed to each
2830     * process when the bindApplication() IPC is sent to the process. They're
2831     * lazily setup to make sure the services are running when they're asked for.
2832     */
2833    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2834        if (mAppBindArgs == null) {
2835            mAppBindArgs = new HashMap<>();
2836
2837            // Isolated processes won't get this optimization, so that we don't
2838            // violate the rules about which services they have access to.
2839            if (!isolated) {
2840                // Setup the application init args
2841                mAppBindArgs.put("package", ServiceManager.getService("package"));
2842                mAppBindArgs.put("window", ServiceManager.getService("window"));
2843                mAppBindArgs.put(Context.ALARM_SERVICE,
2844                        ServiceManager.getService(Context.ALARM_SERVICE));
2845            }
2846        }
2847        return mAppBindArgs;
2848    }
2849
2850    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2851        if (r == null || mFocusedActivity == r) {
2852            return false;
2853        }
2854
2855        if (!r.isFocusable()) {
2856            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2857            return false;
2858        }
2859
2860        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2861
2862        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2863        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2864                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2865        mDoingSetFocusedActivity = true;
2866
2867        final ActivityRecord last = mFocusedActivity;
2868        mFocusedActivity = r;
2869        if (r.task.isApplicationTask()) {
2870            if (mCurAppTimeTracker != r.appTimeTracker) {
2871                // We are switching app tracking.  Complete the current one.
2872                if (mCurAppTimeTracker != null) {
2873                    mCurAppTimeTracker.stop();
2874                    mHandler.obtainMessage(
2875                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2876                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2877                    mCurAppTimeTracker = null;
2878                }
2879                if (r.appTimeTracker != null) {
2880                    mCurAppTimeTracker = r.appTimeTracker;
2881                    startTimeTrackingFocusedActivityLocked();
2882                }
2883            } else {
2884                startTimeTrackingFocusedActivityLocked();
2885            }
2886        } else {
2887            r.appTimeTracker = null;
2888        }
2889        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2890        // TODO: Probably not, because we don't want to resume voice on switching
2891        // back to this activity
2892        if (r.task.voiceInteractor != null) {
2893            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2894        } else {
2895            finishRunningVoiceLocked();
2896            IVoiceInteractionSession session;
2897            if (last != null && ((session = last.task.voiceSession) != null
2898                    || (session = last.voiceSession) != null)) {
2899                // We had been in a voice interaction session, but now focused has
2900                // move to something different.  Just finish the session, we can't
2901                // return to it and retain the proper state and synchronization with
2902                // the voice interaction service.
2903                finishVoiceTask(session);
2904            }
2905        }
2906        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2907            mWindowManager.setFocusedApp(r.appToken, true);
2908        }
2909        applyUpdateLockStateLocked(r);
2910        applyUpdateVrModeLocked(r);
2911        if (mFocusedActivity.userId != mLastFocusedUserId) {
2912            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2913            mHandler.obtainMessage(
2914                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2915            mLastFocusedUserId = mFocusedActivity.userId;
2916        }
2917
2918        // Log a warning if the focused app is changed during the process. This could
2919        // indicate a problem of the focus setting logic!
2920        if (mFocusedActivity != r) Slog.w(TAG,
2921                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2922        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2923
2924        EventLogTags.writeAmFocusedActivity(
2925                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2926                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2927                reason);
2928        return true;
2929    }
2930
2931    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2932        if (mFocusedActivity != goingAway) {
2933            return;
2934        }
2935
2936        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2937        if (focusedStack != null) {
2938            final ActivityRecord top = focusedStack.topActivity();
2939            if (top != null && top.userId != mLastFocusedUserId) {
2940                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2941                mHandler.sendMessage(
2942                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2943                mLastFocusedUserId = top.userId;
2944            }
2945        }
2946
2947        // Try to move focus to another activity if possible.
2948        if (setFocusedActivityLocked(
2949                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2950            return;
2951        }
2952
2953        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2954                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2955        mFocusedActivity = null;
2956        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2957    }
2958
2959    @Override
2960    public void setFocusedStack(int stackId) {
2961        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2962        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2963        final long callingId = Binder.clearCallingIdentity();
2964        try {
2965            synchronized (this) {
2966                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2967                if (stack == null) {
2968                    return;
2969                }
2970                final ActivityRecord r = stack.topRunningActivityLocked();
2971                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2972                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2973                }
2974            }
2975        } finally {
2976            Binder.restoreCallingIdentity(callingId);
2977        }
2978    }
2979
2980    @Override
2981    public void setFocusedTask(int taskId) {
2982        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2983        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2984        final long callingId = Binder.clearCallingIdentity();
2985        try {
2986            synchronized (this) {
2987                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2988                if (task == null) {
2989                    return;
2990                }
2991                final ActivityRecord r = task.topRunningActivityLocked();
2992                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2993                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2994                }
2995            }
2996        } finally {
2997            Binder.restoreCallingIdentity(callingId);
2998        }
2999    }
3000
3001    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3002    @Override
3003    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3004        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3005        synchronized (this) {
3006            if (listener != null) {
3007                mTaskStackListeners.register(listener);
3008            }
3009        }
3010    }
3011
3012    @Override
3013    public void notifyActivityDrawn(IBinder token) {
3014        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3015        synchronized (this) {
3016            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3017            if (r != null) {
3018                r.task.stack.notifyActivityDrawnLocked(r);
3019            }
3020        }
3021    }
3022
3023    final void applyUpdateLockStateLocked(ActivityRecord r) {
3024        // Modifications to the UpdateLock state are done on our handler, outside
3025        // the activity manager's locks.  The new state is determined based on the
3026        // state *now* of the relevant activity record.  The object is passed to
3027        // the handler solely for logging detail, not to be consulted/modified.
3028        final boolean nextState = r != null && r.immersive;
3029        mHandler.sendMessage(
3030                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3031    }
3032
3033    final void applyUpdateVrModeLocked(ActivityRecord r) {
3034        mHandler.sendMessage(
3035                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3036    }
3037
3038    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3039        mHandler.sendMessage(
3040                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3041    }
3042
3043    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3044        Message msg = Message.obtain();
3045        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3046        msg.obj = r.task.askedCompatMode ? null : r;
3047        mUiHandler.sendMessage(msg);
3048    }
3049
3050    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3051            String what, Object obj, ProcessRecord srcApp) {
3052        app.lastActivityTime = now;
3053
3054        if (app.activities.size() > 0) {
3055            // Don't want to touch dependent processes that are hosting activities.
3056            return index;
3057        }
3058
3059        int lrui = mLruProcesses.lastIndexOf(app);
3060        if (lrui < 0) {
3061            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3062                    + what + " " + obj + " from " + srcApp);
3063            return index;
3064        }
3065
3066        if (lrui >= index) {
3067            // Don't want to cause this to move dependent processes *back* in the
3068            // list as if they were less frequently used.
3069            return index;
3070        }
3071
3072        if (lrui >= mLruProcessActivityStart) {
3073            // Don't want to touch dependent processes that are hosting activities.
3074            return index;
3075        }
3076
3077        mLruProcesses.remove(lrui);
3078        if (index > 0) {
3079            index--;
3080        }
3081        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3082                + " in LRU list: " + app);
3083        mLruProcesses.add(index, app);
3084        return index;
3085    }
3086
3087    static void killProcessGroup(int uid, int pid) {
3088        if (sKillHandler != null) {
3089            sKillHandler.sendMessage(
3090                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3091        } else {
3092            Slog.w(TAG, "Asked to kill process group before system bringup!");
3093            Process.killProcessGroup(uid, pid);
3094        }
3095    }
3096
3097    final void removeLruProcessLocked(ProcessRecord app) {
3098        int lrui = mLruProcesses.lastIndexOf(app);
3099        if (lrui >= 0) {
3100            if (!app.killed) {
3101                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3102                Process.killProcessQuiet(app.pid);
3103                killProcessGroup(app.uid, app.pid);
3104            }
3105            if (lrui <= mLruProcessActivityStart) {
3106                mLruProcessActivityStart--;
3107            }
3108            if (lrui <= mLruProcessServiceStart) {
3109                mLruProcessServiceStart--;
3110            }
3111            mLruProcesses.remove(lrui);
3112        }
3113    }
3114
3115    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3116            ProcessRecord client) {
3117        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3118                || app.treatLikeActivity;
3119        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3120        if (!activityChange && hasActivity) {
3121            // The process has activities, so we are only allowing activity-based adjustments
3122            // to move it.  It should be kept in the front of the list with other
3123            // processes that have activities, and we don't want those to change their
3124            // order except due to activity operations.
3125            return;
3126        }
3127
3128        mLruSeq++;
3129        final long now = SystemClock.uptimeMillis();
3130        app.lastActivityTime = now;
3131
3132        // First a quick reject: if the app is already at the position we will
3133        // put it, then there is nothing to do.
3134        if (hasActivity) {
3135            final int N = mLruProcesses.size();
3136            if (N > 0 && mLruProcesses.get(N-1) == app) {
3137                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3138                return;
3139            }
3140        } else {
3141            if (mLruProcessServiceStart > 0
3142                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3143                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3144                return;
3145            }
3146        }
3147
3148        int lrui = mLruProcesses.lastIndexOf(app);
3149
3150        if (app.persistent && lrui >= 0) {
3151            // We don't care about the position of persistent processes, as long as
3152            // they are in the list.
3153            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3154            return;
3155        }
3156
3157        /* In progress: compute new position first, so we can avoid doing work
3158           if the process is not actually going to move.  Not yet working.
3159        int addIndex;
3160        int nextIndex;
3161        boolean inActivity = false, inService = false;
3162        if (hasActivity) {
3163            // Process has activities, put it at the very tipsy-top.
3164            addIndex = mLruProcesses.size();
3165            nextIndex = mLruProcessServiceStart;
3166            inActivity = true;
3167        } else if (hasService) {
3168            // Process has services, put it at the top of the service list.
3169            addIndex = mLruProcessActivityStart;
3170            nextIndex = mLruProcessServiceStart;
3171            inActivity = true;
3172            inService = true;
3173        } else  {
3174            // Process not otherwise of interest, it goes to the top of the non-service area.
3175            addIndex = mLruProcessServiceStart;
3176            if (client != null) {
3177                int clientIndex = mLruProcesses.lastIndexOf(client);
3178                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3179                        + app);
3180                if (clientIndex >= 0 && addIndex > clientIndex) {
3181                    addIndex = clientIndex;
3182                }
3183            }
3184            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3185        }
3186
3187        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3188                + mLruProcessActivityStart + "): " + app);
3189        */
3190
3191        if (lrui >= 0) {
3192            if (lrui < mLruProcessActivityStart) {
3193                mLruProcessActivityStart--;
3194            }
3195            if (lrui < mLruProcessServiceStart) {
3196                mLruProcessServiceStart--;
3197            }
3198            /*
3199            if (addIndex > lrui) {
3200                addIndex--;
3201            }
3202            if (nextIndex > lrui) {
3203                nextIndex--;
3204            }
3205            */
3206            mLruProcesses.remove(lrui);
3207        }
3208
3209        /*
3210        mLruProcesses.add(addIndex, app);
3211        if (inActivity) {
3212            mLruProcessActivityStart++;
3213        }
3214        if (inService) {
3215            mLruProcessActivityStart++;
3216        }
3217        */
3218
3219        int nextIndex;
3220        if (hasActivity) {
3221            final int N = mLruProcesses.size();
3222            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3223                // Process doesn't have activities, but has clients with
3224                // activities...  move it up, but one below the top (the top
3225                // should always have a real activity).
3226                if (DEBUG_LRU) Slog.d(TAG_LRU,
3227                        "Adding to second-top of LRU activity list: " + app);
3228                mLruProcesses.add(N - 1, app);
3229                // To keep it from spamming the LRU list (by making a bunch of clients),
3230                // we will push down any other entries owned by the app.
3231                final int uid = app.info.uid;
3232                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3233                    ProcessRecord subProc = mLruProcesses.get(i);
3234                    if (subProc.info.uid == uid) {
3235                        // We want to push this one down the list.  If the process after
3236                        // it is for the same uid, however, don't do so, because we don't
3237                        // want them internally to be re-ordered.
3238                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3239                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3240                                    "Pushing uid " + uid + " swapping at " + i + ": "
3241                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3242                            ProcessRecord tmp = mLruProcesses.get(i);
3243                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3244                            mLruProcesses.set(i - 1, tmp);
3245                            i--;
3246                        }
3247                    } else {
3248                        // A gap, we can stop here.
3249                        break;
3250                    }
3251                }
3252            } else {
3253                // Process has activities, put it at the very tipsy-top.
3254                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3255                mLruProcesses.add(app);
3256            }
3257            nextIndex = mLruProcessServiceStart;
3258        } else if (hasService) {
3259            // Process has services, put it at the top of the service list.
3260            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3261            mLruProcesses.add(mLruProcessActivityStart, app);
3262            nextIndex = mLruProcessServiceStart;
3263            mLruProcessActivityStart++;
3264        } else  {
3265            // Process not otherwise of interest, it goes to the top of the non-service area.
3266            int index = mLruProcessServiceStart;
3267            if (client != null) {
3268                // If there is a client, don't allow the process to be moved up higher
3269                // in the list than that client.
3270                int clientIndex = mLruProcesses.lastIndexOf(client);
3271                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3272                        + " when updating " + app);
3273                if (clientIndex <= lrui) {
3274                    // Don't allow the client index restriction to push it down farther in the
3275                    // list than it already is.
3276                    clientIndex = lrui;
3277                }
3278                if (clientIndex >= 0 && index > clientIndex) {
3279                    index = clientIndex;
3280                }
3281            }
3282            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3283            mLruProcesses.add(index, app);
3284            nextIndex = index-1;
3285            mLruProcessActivityStart++;
3286            mLruProcessServiceStart++;
3287        }
3288
3289        // If the app is currently using a content provider or service,
3290        // bump those processes as well.
3291        for (int j=app.connections.size()-1; j>=0; j--) {
3292            ConnectionRecord cr = app.connections.valueAt(j);
3293            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3294                    && cr.binding.service.app != null
3295                    && cr.binding.service.app.lruSeq != mLruSeq
3296                    && !cr.binding.service.app.persistent) {
3297                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3298                        "service connection", cr, app);
3299            }
3300        }
3301        for (int j=app.conProviders.size()-1; j>=0; j--) {
3302            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3303            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3304                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3305                        "provider reference", cpr, app);
3306            }
3307        }
3308    }
3309
3310    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3311        if (uid == Process.SYSTEM_UID) {
3312            // The system gets to run in any process.  If there are multiple
3313            // processes with the same uid, just pick the first (this
3314            // should never happen).
3315            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3316            if (procs == null) return null;
3317            final int procCount = procs.size();
3318            for (int i = 0; i < procCount; i++) {
3319                final int procUid = procs.keyAt(i);
3320                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3321                    // Don't use an app process or different user process for system component.
3322                    continue;
3323                }
3324                return procs.valueAt(i);
3325            }
3326        }
3327        ProcessRecord proc = mProcessNames.get(processName, uid);
3328        if (false && proc != null && !keepIfLarge
3329                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3330                && proc.lastCachedPss >= 4000) {
3331            // Turn this condition on to cause killing to happen regularly, for testing.
3332            if (proc.baseProcessTracker != null) {
3333                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3334            }
3335            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3336        } else if (proc != null && !keepIfLarge
3337                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3338                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3339            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3340            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3341                if (proc.baseProcessTracker != null) {
3342                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3343                }
3344                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3345            }
3346        }
3347        return proc;
3348    }
3349
3350    void notifyPackageUse(String packageName) {
3351        IPackageManager pm = AppGlobals.getPackageManager();
3352        try {
3353            pm.notifyPackageUse(packageName);
3354        } catch (RemoteException e) {
3355        }
3356    }
3357
3358    boolean isNextTransitionForward() {
3359        int transit = mWindowManager.getPendingAppTransition();
3360        return transit == TRANSIT_ACTIVITY_OPEN
3361                || transit == TRANSIT_TASK_OPEN
3362                || transit == TRANSIT_TASK_TO_FRONT;
3363    }
3364
3365    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3366            String processName, String abiOverride, int uid, Runnable crashHandler) {
3367        synchronized(this) {
3368            ApplicationInfo info = new ApplicationInfo();
3369            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3370            // For isolated processes, the former contains the parent's uid and the latter the
3371            // actual uid of the isolated process.
3372            // In the special case introduced by this method (which is, starting an isolated
3373            // process directly from the SystemServer without an actual parent app process) the
3374            // closest thing to a parent's uid is SYSTEM_UID.
3375            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3376            // the |isolated| logic in the ProcessRecord constructor.
3377            info.uid = Process.SYSTEM_UID;
3378            info.processName = processName;
3379            info.className = entryPoint;
3380            info.packageName = "android";
3381            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3382                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3383                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3384                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3385                    crashHandler);
3386            return proc != null ? proc.pid : 0;
3387        }
3388    }
3389
3390    final ProcessRecord startProcessLocked(String processName,
3391            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3392            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3393            boolean isolated, boolean keepIfLarge) {
3394        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3395                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3396                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3397                null /* crashHandler */);
3398    }
3399
3400    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3401            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3402            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3403            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3404        long startTime = SystemClock.elapsedRealtime();
3405        ProcessRecord app;
3406        if (!isolated) {
3407            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3408            checkTime(startTime, "startProcess: after getProcessRecord");
3409
3410            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3411                // If we are in the background, then check to see if this process
3412                // is bad.  If so, we will just silently fail.
3413                if (mAppErrors.isBadProcessLocked(info)) {
3414                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3415                            + "/" + info.processName);
3416                    return null;
3417                }
3418            } else {
3419                // When the user is explicitly starting a process, then clear its
3420                // crash count so that we won't make it bad until they see at
3421                // least one crash dialog again, and make the process good again
3422                // if it had been bad.
3423                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3424                        + "/" + info.processName);
3425                mAppErrors.resetProcessCrashTimeLocked(info);
3426                if (mAppErrors.isBadProcessLocked(info)) {
3427                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3428                            UserHandle.getUserId(info.uid), info.uid,
3429                            info.processName);
3430                    mAppErrors.clearBadProcessLocked(info);
3431                    if (app != null) {
3432                        app.bad = false;
3433                    }
3434                }
3435            }
3436        } else {
3437            // If this is an isolated process, it can't re-use an existing process.
3438            app = null;
3439        }
3440
3441        // app launch boost for big.little configurations
3442        // use cpusets to migrate freshly launched tasks to big cores
3443        synchronized(ActivityManagerService.this) {
3444            nativeMigrateToBoost();
3445            mIsBoosted = true;
3446            mBoostStartTime = SystemClock.uptimeMillis();
3447            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3448            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3449        }
3450
3451        // We don't have to do anything more if:
3452        // (1) There is an existing application record; and
3453        // (2) The caller doesn't think it is dead, OR there is no thread
3454        //     object attached to it so we know it couldn't have crashed; and
3455        // (3) There is a pid assigned to it, so it is either starting or
3456        //     already running.
3457        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3458                + " app=" + app + " knownToBeDead=" + knownToBeDead
3459                + " thread=" + (app != null ? app.thread : null)
3460                + " pid=" + (app != null ? app.pid : -1));
3461        if (app != null && app.pid > 0) {
3462            if (!knownToBeDead || app.thread == null) {
3463                // We already have the app running, or are waiting for it to
3464                // come up (we have a pid but not yet its thread), so keep it.
3465                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3466                // If this is a new package in the process, add the package to the list
3467                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3468                checkTime(startTime, "startProcess: done, added package to proc");
3469                return app;
3470            }
3471
3472            // An application record is attached to a previous process,
3473            // clean it up now.
3474            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3475            checkTime(startTime, "startProcess: bad proc running, killing");
3476            killProcessGroup(app.uid, app.pid);
3477            handleAppDiedLocked(app, true, true);
3478            checkTime(startTime, "startProcess: done killing old proc");
3479        }
3480
3481        String hostingNameStr = hostingName != null
3482                ? hostingName.flattenToShortString() : null;
3483
3484        if (app == null) {
3485            checkTime(startTime, "startProcess: creating new process record");
3486            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3487            if (app == null) {
3488                Slog.w(TAG, "Failed making new process record for "
3489                        + processName + "/" + info.uid + " isolated=" + isolated);
3490                return null;
3491            }
3492            app.crashHandler = crashHandler;
3493            checkTime(startTime, "startProcess: done creating new process record");
3494        } else {
3495            // If this is a new package in the process, add the package to the list
3496            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3497            checkTime(startTime, "startProcess: added package to existing proc");
3498        }
3499
3500        // If the system is not ready yet, then hold off on starting this
3501        // process until it is.
3502        if (!mProcessesReady
3503                && !isAllowedWhileBooting(info)
3504                && !allowWhileBooting) {
3505            if (!mProcessesOnHold.contains(app)) {
3506                mProcessesOnHold.add(app);
3507            }
3508            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3509                    "System not ready, putting on hold: " + app);
3510            checkTime(startTime, "startProcess: returning with proc on hold");
3511            return app;
3512        }
3513
3514        checkTime(startTime, "startProcess: stepping in to startProcess");
3515        startProcessLocked(
3516                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3517        checkTime(startTime, "startProcess: done starting proc!");
3518        return (app.pid != 0) ? app : null;
3519    }
3520
3521    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3522        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3523    }
3524
3525    private final void startProcessLocked(ProcessRecord app,
3526            String hostingType, String hostingNameStr) {
3527        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3528                null /* entryPoint */, null /* entryPointArgs */);
3529    }
3530
3531    private final void startProcessLocked(ProcessRecord app, String hostingType,
3532            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3533        long startTime = SystemClock.elapsedRealtime();
3534        if (app.pid > 0 && app.pid != MY_PID) {
3535            checkTime(startTime, "startProcess: removing from pids map");
3536            synchronized (mPidsSelfLocked) {
3537                mPidsSelfLocked.remove(app.pid);
3538                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3539            }
3540            checkTime(startTime, "startProcess: done removing from pids map");
3541            app.setPid(0);
3542        }
3543
3544        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3545                "startProcessLocked removing on hold: " + app);
3546        mProcessesOnHold.remove(app);
3547
3548        checkTime(startTime, "startProcess: starting to update cpu stats");
3549        updateCpuStats();
3550        checkTime(startTime, "startProcess: done updating cpu stats");
3551
3552        try {
3553            try {
3554                final int userId = UserHandle.getUserId(app.uid);
3555                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3556            } catch (RemoteException e) {
3557                throw e.rethrowAsRuntimeException();
3558            }
3559
3560            int uid = app.uid;
3561            int[] gids = null;
3562            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3563            if (!app.isolated) {
3564                int[] permGids = null;
3565                try {
3566                    checkTime(startTime, "startProcess: getting gids from package manager");
3567                    final IPackageManager pm = AppGlobals.getPackageManager();
3568                    permGids = pm.getPackageGids(app.info.packageName,
3569                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3570                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3571                            MountServiceInternal.class);
3572                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3573                            app.info.packageName);
3574                } catch (RemoteException e) {
3575                    throw e.rethrowAsRuntimeException();
3576                }
3577
3578                /*
3579                 * Add shared application and profile GIDs so applications can share some
3580                 * resources like shared libraries and access user-wide resources
3581                 */
3582                if (ArrayUtils.isEmpty(permGids)) {
3583                    gids = new int[2];
3584                } else {
3585                    gids = new int[permGids.length + 2];
3586                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3587                }
3588                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3589                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3590            }
3591            checkTime(startTime, "startProcess: building args");
3592            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3593                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3594                        && mTopComponent != null
3595                        && app.processName.equals(mTopComponent.getPackageName())) {
3596                    uid = 0;
3597                }
3598                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3599                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3600                    uid = 0;
3601                }
3602            }
3603            int debugFlags = 0;
3604            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3605                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3606                // Also turn on CheckJNI for debuggable apps. It's quite
3607                // awkward to turn on otherwise.
3608                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3609            }
3610            // Run the app in safe mode if its manifest requests so or the
3611            // system is booted in safe mode.
3612            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3613                mSafeMode == true) {
3614                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3615            }
3616            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3617                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3618            }
3619            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3620            if ("true".equals(genDebugInfoProperty)) {
3621                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3622            }
3623            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3624                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3625            }
3626            if ("1".equals(SystemProperties.get("debug.assert"))) {
3627                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3628            }
3629            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3630                // Enable all debug flags required by the native debugger.
3631                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3632                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3633                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3634                mNativeDebuggingApp = null;
3635            }
3636
3637            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3638            if (requiredAbi == null) {
3639                requiredAbi = Build.SUPPORTED_ABIS[0];
3640            }
3641
3642            String instructionSet = null;
3643            if (app.info.primaryCpuAbi != null) {
3644                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3645            }
3646
3647            app.gids = gids;
3648            app.requiredAbi = requiredAbi;
3649            app.instructionSet = instructionSet;
3650
3651            // Start the process.  It will either succeed and return a result containing
3652            // the PID of the new process, or else throw a RuntimeException.
3653            boolean isActivityProcess = (entryPoint == null);
3654            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3655            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3656                    app.processName);
3657            checkTime(startTime, "startProcess: asking zygote to start proc");
3658            Process.ProcessStartResult startResult = Process.start(entryPoint,
3659                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3660                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3661                    app.info.dataDir, entryPointArgs);
3662            checkTime(startTime, "startProcess: returned from zygote!");
3663            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3664
3665            if (app.isolated) {
3666                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3667            }
3668            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3669            checkTime(startTime, "startProcess: done updating battery stats");
3670
3671            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3672                    UserHandle.getUserId(uid), startResult.pid, uid,
3673                    app.processName, hostingType,
3674                    hostingNameStr != null ? hostingNameStr : "");
3675
3676            try {
3677                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3678                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3679            } catch (RemoteException ex) {
3680                // Ignore
3681            }
3682
3683            if (app.persistent) {
3684                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3685            }
3686
3687            if (DEBUG_PROCESSES) {
3688                checkTime(startTime, "startProcess: building log message");
3689                StringBuilder buf = mStringBuilder;
3690                buf.setLength(0);
3691                buf.append("Start proc ");
3692                buf.append(startResult.pid);
3693                buf.append(':');
3694                buf.append(app.processName);
3695                buf.append('/');
3696                UserHandle.formatUid(buf, uid);
3697                if (!isActivityProcess) {
3698                    buf.append(" [");
3699                    buf.append(entryPoint);
3700                    buf.append("]");
3701                }
3702                buf.append(" for ");
3703                buf.append(hostingType);
3704                if (hostingNameStr != null) {
3705                    buf.append(" ");
3706                    buf.append(hostingNameStr);
3707                }
3708                Slog.i(TAG, buf.toString());
3709            }
3710            app.setPid(startResult.pid);
3711            app.usingWrapper = startResult.usingWrapper;
3712            app.removed = false;
3713            app.killed = false;
3714            app.killedByAm = false;
3715            checkTime(startTime, "startProcess: starting to update pids map");
3716            synchronized (mPidsSelfLocked) {
3717                this.mPidsSelfLocked.put(startResult.pid, app);
3718                if (isActivityProcess) {
3719                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3720                    msg.obj = app;
3721                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3722                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3723                }
3724            }
3725            checkTime(startTime, "startProcess: done updating pids map");
3726        } catch (RuntimeException e) {
3727            // XXX do better error recovery.
3728            app.setPid(0);
3729            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3730            if (app.isolated) {
3731                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3732            }
3733            Slog.e(TAG, "Failure starting process " + app.processName, e);
3734        }
3735    }
3736
3737    void updateUsageStats(ActivityRecord component, boolean resumed) {
3738        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3739                "updateUsageStats: comp=" + component + "res=" + resumed);
3740        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3741        if (resumed) {
3742            if (mUsageStatsService != null) {
3743                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3744                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3745            }
3746            synchronized (stats) {
3747                stats.noteActivityResumedLocked(component.app.uid);
3748            }
3749        } else {
3750            if (mUsageStatsService != null) {
3751                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3752                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3753            }
3754            synchronized (stats) {
3755                stats.noteActivityPausedLocked(component.app.uid);
3756            }
3757        }
3758    }
3759
3760    Intent getHomeIntent() {
3761        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3762        intent.setComponent(mTopComponent);
3763        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3764        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3765            intent.addCategory(Intent.CATEGORY_HOME);
3766        }
3767        return intent;
3768    }
3769
3770    boolean startHomeActivityLocked(int userId, String reason) {
3771        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3772                && mTopAction == null) {
3773            // We are running in factory test mode, but unable to find
3774            // the factory test app, so just sit around displaying the
3775            // error message and don't try to start anything.
3776            return false;
3777        }
3778        Intent intent = getHomeIntent();
3779        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3780        if (aInfo != null) {
3781            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3782            // Don't do this if the home app is currently being
3783            // instrumented.
3784            aInfo = new ActivityInfo(aInfo);
3785            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3786            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3787                    aInfo.applicationInfo.uid, true);
3788            if (app == null || app.instrumentationClass == null) {
3789                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3790                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3791            }
3792        }
3793
3794        return true;
3795    }
3796
3797    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3798        ActivityInfo ai = null;
3799        ComponentName comp = intent.getComponent();
3800        try {
3801            if (comp != null) {
3802                // Factory test.
3803                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3804            } else {
3805                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3806                        intent,
3807                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3808                        flags, userId);
3809
3810                if (info != null) {
3811                    ai = info.activityInfo;
3812                }
3813            }
3814        } catch (RemoteException e) {
3815            // ignore
3816        }
3817
3818        return ai;
3819    }
3820
3821    /**
3822     * Starts the "new version setup screen" if appropriate.
3823     */
3824    void startSetupActivityLocked() {
3825        // Only do this once per boot.
3826        if (mCheckedForSetup) {
3827            return;
3828        }
3829
3830        // We will show this screen if the current one is a different
3831        // version than the last one shown, and we are not running in
3832        // low-level factory test mode.
3833        final ContentResolver resolver = mContext.getContentResolver();
3834        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3835                Settings.Global.getInt(resolver,
3836                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3837            mCheckedForSetup = true;
3838
3839            // See if we should be showing the platform update setup UI.
3840            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3841            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3842                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3843            if (!ris.isEmpty()) {
3844                final ResolveInfo ri = ris.get(0);
3845                String vers = ri.activityInfo.metaData != null
3846                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3847                        : null;
3848                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3849                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3850                            Intent.METADATA_SETUP_VERSION);
3851                }
3852                String lastVers = Settings.Secure.getString(
3853                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3854                if (vers != null && !vers.equals(lastVers)) {
3855                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3856                    intent.setComponent(new ComponentName(
3857                            ri.activityInfo.packageName, ri.activityInfo.name));
3858                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3859                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3860                            null, 0, 0, 0, null, false, false, null, null, null);
3861                }
3862            }
3863        }
3864    }
3865
3866    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3867        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3868    }
3869
3870    void enforceNotIsolatedCaller(String caller) {
3871        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3872            throw new SecurityException("Isolated process not allowed to call " + caller);
3873        }
3874    }
3875
3876    void enforceShellRestriction(String restriction, int userHandle) {
3877        if (Binder.getCallingUid() == Process.SHELL_UID) {
3878            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3879                throw new SecurityException("Shell does not have permission to access user "
3880                        + userHandle);
3881            }
3882        }
3883    }
3884
3885    @Override
3886    public int getFrontActivityScreenCompatMode() {
3887        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3888        synchronized (this) {
3889            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3890        }
3891    }
3892
3893    @Override
3894    public void setFrontActivityScreenCompatMode(int mode) {
3895        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3896                "setFrontActivityScreenCompatMode");
3897        synchronized (this) {
3898            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3899        }
3900    }
3901
3902    @Override
3903    public int getPackageScreenCompatMode(String packageName) {
3904        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3905        synchronized (this) {
3906            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3907        }
3908    }
3909
3910    @Override
3911    public void setPackageScreenCompatMode(String packageName, int mode) {
3912        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3913                "setPackageScreenCompatMode");
3914        synchronized (this) {
3915            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3916        }
3917    }
3918
3919    @Override
3920    public boolean getPackageAskScreenCompat(String packageName) {
3921        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3922        synchronized (this) {
3923            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3924        }
3925    }
3926
3927    @Override
3928    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3929        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3930                "setPackageAskScreenCompat");
3931        synchronized (this) {
3932            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3933        }
3934    }
3935
3936    private boolean hasUsageStatsPermission(String callingPackage) {
3937        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3938                Binder.getCallingUid(), callingPackage);
3939        if (mode == AppOpsManager.MODE_DEFAULT) {
3940            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3941                    == PackageManager.PERMISSION_GRANTED;
3942        }
3943        return mode == AppOpsManager.MODE_ALLOWED;
3944    }
3945
3946    @Override
3947    public int getPackageProcessState(String packageName, String callingPackage) {
3948        if (!hasUsageStatsPermission(callingPackage)) {
3949            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3950                    "getPackageProcessState");
3951        }
3952
3953        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3954        synchronized (this) {
3955            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3956                final ProcessRecord proc = mLruProcesses.get(i);
3957                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3958                        || procState > proc.setProcState) {
3959                    boolean found = false;
3960                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3961                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3962                            procState = proc.setProcState;
3963                            found = true;
3964                        }
3965                    }
3966                    if (proc.pkgDeps != null && !found) {
3967                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3968                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3969                                procState = proc.setProcState;
3970                                break;
3971                            }
3972                        }
3973                    }
3974                }
3975            }
3976        }
3977        return procState;
3978    }
3979
3980    @Override
3981    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3982        synchronized (this) {
3983            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3984            if (app == null) {
3985                return false;
3986            }
3987            if (app.trimMemoryLevel < level && app.thread != null &&
3988                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3989                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3990                try {
3991                    app.thread.scheduleTrimMemory(level);
3992                    app.trimMemoryLevel = level;
3993                    return true;
3994                } catch (RemoteException e) {
3995                    // Fallthrough to failure case.
3996                }
3997            }
3998        }
3999        return false;
4000    }
4001
4002    private void dispatchProcessesChanged() {
4003        int N;
4004        synchronized (this) {
4005            N = mPendingProcessChanges.size();
4006            if (mActiveProcessChanges.length < N) {
4007                mActiveProcessChanges = new ProcessChangeItem[N];
4008            }
4009            mPendingProcessChanges.toArray(mActiveProcessChanges);
4010            mPendingProcessChanges.clear();
4011            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4012                    "*** Delivering " + N + " process changes");
4013        }
4014
4015        int i = mProcessObservers.beginBroadcast();
4016        while (i > 0) {
4017            i--;
4018            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4019            if (observer != null) {
4020                try {
4021                    for (int j=0; j<N; j++) {
4022                        ProcessChangeItem item = mActiveProcessChanges[j];
4023                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4024                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4025                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4026                                    + item.uid + ": " + item.foregroundActivities);
4027                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4028                                    item.foregroundActivities);
4029                        }
4030                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4031                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4032                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4033                                    + ": " + item.processState);
4034                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4035                        }
4036                    }
4037                } catch (RemoteException e) {
4038                }
4039            }
4040        }
4041        mProcessObservers.finishBroadcast();
4042
4043        synchronized (this) {
4044            for (int j=0; j<N; j++) {
4045                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4046            }
4047        }
4048    }
4049
4050    private void dispatchProcessDied(int pid, int uid) {
4051        int i = mProcessObservers.beginBroadcast();
4052        while (i > 0) {
4053            i--;
4054            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4055            if (observer != null) {
4056                try {
4057                    observer.onProcessDied(pid, uid);
4058                } catch (RemoteException e) {
4059                }
4060            }
4061        }
4062        mProcessObservers.finishBroadcast();
4063    }
4064
4065    private void dispatchUidsChanged() {
4066        int N;
4067        synchronized (this) {
4068            N = mPendingUidChanges.size();
4069            if (mActiveUidChanges.length < N) {
4070                mActiveUidChanges = new UidRecord.ChangeItem[N];
4071            }
4072            for (int i=0; i<N; i++) {
4073                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4074                mActiveUidChanges[i] = change;
4075                if (change.uidRecord != null) {
4076                    change.uidRecord.pendingChange = null;
4077                    change.uidRecord = null;
4078                }
4079            }
4080            mPendingUidChanges.clear();
4081            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4082                    "*** Delivering " + N + " uid changes");
4083        }
4084
4085        if (mLocalPowerManager != null) {
4086            for (int j=0; j<N; j++) {
4087                UidRecord.ChangeItem item = mActiveUidChanges[j];
4088                if (item.change == UidRecord.CHANGE_GONE
4089                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4090                    mLocalPowerManager.uidGone(item.uid);
4091                } else {
4092                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4093                }
4094            }
4095        }
4096
4097        int i = mUidObservers.beginBroadcast();
4098        while (i > 0) {
4099            i--;
4100            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4101            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4102            if (observer != null) {
4103                try {
4104                    for (int j=0; j<N; j++) {
4105                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4106                        final int change = item.change;
4107                        UidRecord validateUid = null;
4108                        if (VALIDATE_UID_STATES && i == 0) {
4109                            validateUid = mValidateUids.get(item.uid);
4110                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4111                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4112                                validateUid = new UidRecord(item.uid);
4113                                mValidateUids.put(item.uid, validateUid);
4114                            }
4115                        }
4116                        if (change == UidRecord.CHANGE_IDLE
4117                                || change == UidRecord.CHANGE_GONE_IDLE) {
4118                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4119                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4120                                        "UID idle uid=" + item.uid);
4121                                observer.onUidIdle(item.uid);
4122                            }
4123                            if (VALIDATE_UID_STATES && i == 0) {
4124                                if (validateUid != null) {
4125                                    validateUid.idle = true;
4126                                }
4127                            }
4128                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4129                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4130                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4131                                        "UID active uid=" + item.uid);
4132                                observer.onUidActive(item.uid);
4133                            }
4134                            if (VALIDATE_UID_STATES && i == 0) {
4135                                validateUid.idle = false;
4136                            }
4137                        }
4138                        if (change == UidRecord.CHANGE_GONE
4139                                || change == UidRecord.CHANGE_GONE_IDLE) {
4140                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4141                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4142                                        "UID gone uid=" + item.uid);
4143                                observer.onUidGone(item.uid);
4144                            }
4145                            if (VALIDATE_UID_STATES && i == 0) {
4146                                if (validateUid != null) {
4147                                    mValidateUids.remove(item.uid);
4148                                }
4149                            }
4150                        } else {
4151                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4152                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4153                                        "UID CHANGED uid=" + item.uid
4154                                                + ": " + item.processState);
4155                                observer.onUidStateChanged(item.uid, item.processState);
4156                            }
4157                            if (VALIDATE_UID_STATES && i == 0) {
4158                                validateUid.curProcState = validateUid.setProcState
4159                                        = item.processState;
4160                            }
4161                        }
4162                    }
4163                } catch (RemoteException e) {
4164                }
4165            }
4166        }
4167        mUidObservers.finishBroadcast();
4168
4169        synchronized (this) {
4170            for (int j=0; j<N; j++) {
4171                mAvailUidChanges.add(mActiveUidChanges[j]);
4172            }
4173        }
4174    }
4175
4176    @Override
4177    public final int startActivity(IApplicationThread caller, String callingPackage,
4178            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4179            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4180        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4181                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4182                UserHandle.getCallingUserId());
4183    }
4184
4185    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4186        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4187        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4188                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4189                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4190
4191        // TODO: Switch to user app stacks here.
4192        String mimeType = intent.getType();
4193        final Uri data = intent.getData();
4194        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4195            mimeType = getProviderMimeType(data, userId);
4196        }
4197        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4198
4199        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4200        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4201                null, 0, 0, null, null, null, null, false, userId, container, null);
4202    }
4203
4204    @Override
4205    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4206            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4207            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4208        enforceNotIsolatedCaller("startActivity");
4209        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4210                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4211        // TODO: Switch to user app stacks here.
4212        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4213                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4214                profilerInfo, null, null, bOptions, false, userId, null, null);
4215    }
4216
4217    @Override
4218    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4219            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4220            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4221            int userId) {
4222
4223        // This is very dangerous -- it allows you to perform a start activity (including
4224        // permission grants) as any app that may launch one of your own activities.  So
4225        // we will only allow this to be done from activities that are part of the core framework,
4226        // and then only when they are running as the system.
4227        final ActivityRecord sourceRecord;
4228        final int targetUid;
4229        final String targetPackage;
4230        synchronized (this) {
4231            if (resultTo == null) {
4232                throw new SecurityException("Must be called from an activity");
4233            }
4234            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4235            if (sourceRecord == null) {
4236                throw new SecurityException("Called with bad activity token: " + resultTo);
4237            }
4238            if (!sourceRecord.info.packageName.equals("android")) {
4239                throw new SecurityException(
4240                        "Must be called from an activity that is declared in the android package");
4241            }
4242            if (sourceRecord.app == null) {
4243                throw new SecurityException("Called without a process attached to activity");
4244            }
4245            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4246                // This is still okay, as long as this activity is running under the
4247                // uid of the original calling activity.
4248                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4249                    throw new SecurityException(
4250                            "Calling activity in uid " + sourceRecord.app.uid
4251                                    + " must be system uid or original calling uid "
4252                                    + sourceRecord.launchedFromUid);
4253                }
4254            }
4255            if (ignoreTargetSecurity) {
4256                if (intent.getComponent() == null) {
4257                    throw new SecurityException(
4258                            "Component must be specified with ignoreTargetSecurity");
4259                }
4260                if (intent.getSelector() != null) {
4261                    throw new SecurityException(
4262                            "Selector not allowed with ignoreTargetSecurity");
4263                }
4264            }
4265            targetUid = sourceRecord.launchedFromUid;
4266            targetPackage = sourceRecord.launchedFromPackage;
4267        }
4268
4269        if (userId == UserHandle.USER_NULL) {
4270            userId = UserHandle.getUserId(sourceRecord.app.uid);
4271        }
4272
4273        // TODO: Switch to user app stacks here.
4274        try {
4275            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4276                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4277                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4278            return ret;
4279        } catch (SecurityException e) {
4280            // XXX need to figure out how to propagate to original app.
4281            // A SecurityException here is generally actually a fault of the original
4282            // calling activity (such as a fairly granting permissions), so propagate it
4283            // back to them.
4284            /*
4285            StringBuilder msg = new StringBuilder();
4286            msg.append("While launching");
4287            msg.append(intent.toString());
4288            msg.append(": ");
4289            msg.append(e.getMessage());
4290            */
4291            throw e;
4292        }
4293    }
4294
4295    @Override
4296    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4297            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4298            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4299        enforceNotIsolatedCaller("startActivityAndWait");
4300        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4301                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4302        WaitResult res = new WaitResult();
4303        // TODO: Switch to user app stacks here.
4304        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4305                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4306                bOptions, false, userId, null, null);
4307        return res;
4308    }
4309
4310    @Override
4311    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4312            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4313            int startFlags, Configuration config, Bundle bOptions, int userId) {
4314        enforceNotIsolatedCaller("startActivityWithConfig");
4315        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4316                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4317        // TODO: Switch to user app stacks here.
4318        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4319                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4320                null, null, config, bOptions, false, userId, null, null);
4321        return ret;
4322    }
4323
4324    @Override
4325    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4326            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4327            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4328            throws TransactionTooLargeException {
4329        enforceNotIsolatedCaller("startActivityIntentSender");
4330        // Refuse possible leaked file descriptors
4331        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4332            throw new IllegalArgumentException("File descriptors passed in Intent");
4333        }
4334
4335        IIntentSender sender = intent.getTarget();
4336        if (!(sender instanceof PendingIntentRecord)) {
4337            throw new IllegalArgumentException("Bad PendingIntent object");
4338        }
4339
4340        PendingIntentRecord pir = (PendingIntentRecord)sender;
4341
4342        synchronized (this) {
4343            // If this is coming from the currently resumed activity, it is
4344            // effectively saying that app switches are allowed at this point.
4345            final ActivityStack stack = getFocusedStack();
4346            if (stack.mResumedActivity != null &&
4347                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4348                mAppSwitchesAllowedTime = 0;
4349            }
4350        }
4351        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4352                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4353        return ret;
4354    }
4355
4356    @Override
4357    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4358            Intent intent, String resolvedType, IVoiceInteractionSession session,
4359            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4360            Bundle bOptions, int userId) {
4361        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4362                != PackageManager.PERMISSION_GRANTED) {
4363            String msg = "Permission Denial: startVoiceActivity() from pid="
4364                    + Binder.getCallingPid()
4365                    + ", uid=" + Binder.getCallingUid()
4366                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4367            Slog.w(TAG, msg);
4368            throw new SecurityException(msg);
4369        }
4370        if (session == null || interactor == null) {
4371            throw new NullPointerException("null session or interactor");
4372        }
4373        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4374                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4375        // TODO: Switch to user app stacks here.
4376        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4377                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4378                null, bOptions, false, userId, null, null);
4379    }
4380
4381    @Override
4382    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4383            throws RemoteException {
4384        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4385        synchronized (this) {
4386            ActivityRecord activity = getFocusedStack().topActivity();
4387            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4388                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4389            }
4390            if (mRunningVoice != null || activity.task.voiceSession != null
4391                    || activity.voiceSession != null) {
4392                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4393                return;
4394            }
4395            if (activity.pendingVoiceInteractionStart) {
4396                Slog.w(TAG, "Pending start of voice interaction already.");
4397                return;
4398            }
4399            activity.pendingVoiceInteractionStart = true;
4400        }
4401        LocalServices.getService(VoiceInteractionManagerInternal.class)
4402                .startLocalVoiceInteraction(callingActivity, options);
4403    }
4404
4405    @Override
4406    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4407        LocalServices.getService(VoiceInteractionManagerInternal.class)
4408                .stopLocalVoiceInteraction(callingActivity);
4409    }
4410
4411    @Override
4412    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4413        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4414                .supportsLocalVoiceInteraction();
4415    }
4416
4417    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4418            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4419        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4420        if (activityToCallback == null) return;
4421        activityToCallback.setVoiceSessionLocked(voiceSession);
4422
4423        // Inform the activity
4424        try {
4425            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4426                    voiceInteractor);
4427            long token = Binder.clearCallingIdentity();
4428            try {
4429                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4430            } finally {
4431                Binder.restoreCallingIdentity(token);
4432            }
4433            // TODO: VI Should we cache the activity so that it's easier to find later
4434            // rather than scan through all the stacks and activities?
4435        } catch (RemoteException re) {
4436            activityToCallback.clearVoiceSessionLocked();
4437            // TODO: VI Should this terminate the voice session?
4438        }
4439    }
4440
4441    @Override
4442    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4443        synchronized (this) {
4444            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4445                if (keepAwake) {
4446                    mVoiceWakeLock.acquire();
4447                } else {
4448                    mVoiceWakeLock.release();
4449                }
4450            }
4451        }
4452    }
4453
4454    @Override
4455    public boolean startNextMatchingActivity(IBinder callingActivity,
4456            Intent intent, Bundle bOptions) {
4457        // Refuse possible leaked file descriptors
4458        if (intent != null && intent.hasFileDescriptors() == true) {
4459            throw new IllegalArgumentException("File descriptors passed in Intent");
4460        }
4461        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4462
4463        synchronized (this) {
4464            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4465            if (r == null) {
4466                ActivityOptions.abort(options);
4467                return false;
4468            }
4469            if (r.app == null || r.app.thread == null) {
4470                // The caller is not running...  d'oh!
4471                ActivityOptions.abort(options);
4472                return false;
4473            }
4474            intent = new Intent(intent);
4475            // The caller is not allowed to change the data.
4476            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4477            // And we are resetting to find the next component...
4478            intent.setComponent(null);
4479
4480            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4481
4482            ActivityInfo aInfo = null;
4483            try {
4484                List<ResolveInfo> resolves =
4485                    AppGlobals.getPackageManager().queryIntentActivities(
4486                            intent, r.resolvedType,
4487                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4488                            UserHandle.getCallingUserId()).getList();
4489
4490                // Look for the original activity in the list...
4491                final int N = resolves != null ? resolves.size() : 0;
4492                for (int i=0; i<N; i++) {
4493                    ResolveInfo rInfo = resolves.get(i);
4494                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4495                            && rInfo.activityInfo.name.equals(r.info.name)) {
4496                        // We found the current one...  the next matching is
4497                        // after it.
4498                        i++;
4499                        if (i<N) {
4500                            aInfo = resolves.get(i).activityInfo;
4501                        }
4502                        if (debug) {
4503                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4504                                    + "/" + r.info.name);
4505                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4506                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4507                        }
4508                        break;
4509                    }
4510                }
4511            } catch (RemoteException e) {
4512            }
4513
4514            if (aInfo == null) {
4515                // Nobody who is next!
4516                ActivityOptions.abort(options);
4517                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4518                return false;
4519            }
4520
4521            intent.setComponent(new ComponentName(
4522                    aInfo.applicationInfo.packageName, aInfo.name));
4523            intent.setFlags(intent.getFlags()&~(
4524                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4525                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4526                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4527                    Intent.FLAG_ACTIVITY_NEW_TASK));
4528
4529            // Okay now we need to start the new activity, replacing the
4530            // currently running activity.  This is a little tricky because
4531            // we want to start the new one as if the current one is finished,
4532            // but not finish the current one first so that there is no flicker.
4533            // And thus...
4534            final boolean wasFinishing = r.finishing;
4535            r.finishing = true;
4536
4537            // Propagate reply information over to the new activity.
4538            final ActivityRecord resultTo = r.resultTo;
4539            final String resultWho = r.resultWho;
4540            final int requestCode = r.requestCode;
4541            r.resultTo = null;
4542            if (resultTo != null) {
4543                resultTo.removeResultsLocked(r, resultWho, requestCode);
4544            }
4545
4546            final long origId = Binder.clearCallingIdentity();
4547            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4548                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4549                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4550                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4551                    false, false, null, null, null);
4552            Binder.restoreCallingIdentity(origId);
4553
4554            r.finishing = wasFinishing;
4555            if (res != ActivityManager.START_SUCCESS) {
4556                return false;
4557            }
4558            return true;
4559        }
4560    }
4561
4562    @Override
4563    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4564        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4565            String msg = "Permission Denial: startActivityFromRecents called without " +
4566                    START_TASKS_FROM_RECENTS;
4567            Slog.w(TAG, msg);
4568            throw new SecurityException(msg);
4569        }
4570        final long origId = Binder.clearCallingIdentity();
4571        try {
4572            synchronized (this) {
4573                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4574            }
4575        } finally {
4576            Binder.restoreCallingIdentity(origId);
4577        }
4578    }
4579
4580    final int startActivityInPackage(int uid, String callingPackage,
4581            Intent intent, String resolvedType, IBinder resultTo,
4582            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4583            IActivityContainer container, TaskRecord inTask) {
4584
4585        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4586                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4587
4588        // TODO: Switch to user app stacks here.
4589        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4590                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4591                null, null, null, bOptions, false, userId, container, inTask);
4592        return ret;
4593    }
4594
4595    @Override
4596    public final int startActivities(IApplicationThread caller, String callingPackage,
4597            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4598            int userId) {
4599        enforceNotIsolatedCaller("startActivities");
4600        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4601                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4602        // TODO: Switch to user app stacks here.
4603        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4604                resolvedTypes, resultTo, bOptions, userId);
4605        return ret;
4606    }
4607
4608    final int startActivitiesInPackage(int uid, String callingPackage,
4609            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4610            Bundle bOptions, int userId) {
4611
4612        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4613                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4614        // TODO: Switch to user app stacks here.
4615        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4616                resultTo, bOptions, userId);
4617        return ret;
4618    }
4619
4620    @Override
4621    public void reportActivityFullyDrawn(IBinder token) {
4622        synchronized (this) {
4623            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4624            if (r == null) {
4625                return;
4626            }
4627            r.reportFullyDrawnLocked();
4628        }
4629    }
4630
4631    @Override
4632    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4633        synchronized (this) {
4634            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4635            if (r == null) {
4636                return;
4637            }
4638            TaskRecord task = r.task;
4639            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4640                // Fixed screen orientation isn't supported when activities aren't in full screen
4641                // mode.
4642                return;
4643            }
4644            final long origId = Binder.clearCallingIdentity();
4645            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4646            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4647                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4648            if (config != null) {
4649                r.frozenBeforeDestroy = true;
4650                if (!updateConfigurationLocked(config, r, false)) {
4651                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4652                }
4653            }
4654            Binder.restoreCallingIdentity(origId);
4655        }
4656    }
4657
4658    @Override
4659    public int getRequestedOrientation(IBinder token) {
4660        synchronized (this) {
4661            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4662            if (r == null) {
4663                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4664            }
4665            return mWindowManager.getAppOrientation(r.appToken);
4666        }
4667    }
4668
4669    /**
4670     * This is the internal entry point for handling Activity.finish().
4671     *
4672     * @param token The Binder token referencing the Activity we want to finish.
4673     * @param resultCode Result code, if any, from this Activity.
4674     * @param resultData Result data (Intent), if any, from this Activity.
4675     * @param finishTask Whether to finish the task associated with this Activity.
4676     *
4677     * @return Returns true if the activity successfully finished, or false if it is still running.
4678     */
4679    @Override
4680    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4681            int finishTask) {
4682        // Refuse possible leaked file descriptors
4683        if (resultData != null && resultData.hasFileDescriptors() == true) {
4684            throw new IllegalArgumentException("File descriptors passed in Intent");
4685        }
4686
4687        synchronized(this) {
4688            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4689            if (r == null) {
4690                return true;
4691            }
4692            // Keep track of the root activity of the task before we finish it
4693            TaskRecord tr = r.task;
4694            ActivityRecord rootR = tr.getRootActivity();
4695            if (rootR == null) {
4696                Slog.w(TAG, "Finishing task with all activities already finished");
4697            }
4698            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4699            // finish.
4700            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4701                    mStackSupervisor.isLastLockedTask(tr)) {
4702                Slog.i(TAG, "Not finishing task in lock task mode");
4703                mStackSupervisor.showLockTaskToast();
4704                return false;
4705            }
4706            if (mController != null) {
4707                // Find the first activity that is not finishing.
4708                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4709                if (next != null) {
4710                    // ask watcher if this is allowed
4711                    boolean resumeOK = true;
4712                    try {
4713                        resumeOK = mController.activityResuming(next.packageName);
4714                    } catch (RemoteException e) {
4715                        mController = null;
4716                        Watchdog.getInstance().setActivityController(null);
4717                    }
4718
4719                    if (!resumeOK) {
4720                        Slog.i(TAG, "Not finishing activity because controller resumed");
4721                        return false;
4722                    }
4723                }
4724            }
4725            final long origId = Binder.clearCallingIdentity();
4726            try {
4727                boolean res;
4728                final boolean finishWithRootActivity =
4729                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4730                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4731                        || (finishWithRootActivity && r == rootR)) {
4732                    // If requested, remove the task that is associated to this activity only if it
4733                    // was the root activity in the task. The result code and data is ignored
4734                    // because we don't support returning them across task boundaries. Also, to
4735                    // keep backwards compatibility we remove the task from recents when finishing
4736                    // task with root activity.
4737                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4738                    if (!res) {
4739                        Slog.i(TAG, "Removing task failed to finish activity");
4740                    }
4741                } else {
4742                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4743                            resultData, "app-request", true);
4744                    if (!res) {
4745                        Slog.i(TAG, "Failed to finish by app-request");
4746                    }
4747                }
4748                return res;
4749            } finally {
4750                Binder.restoreCallingIdentity(origId);
4751            }
4752        }
4753    }
4754
4755    @Override
4756    public final void finishHeavyWeightApp() {
4757        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4758                != PackageManager.PERMISSION_GRANTED) {
4759            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4760                    + Binder.getCallingPid()
4761                    + ", uid=" + Binder.getCallingUid()
4762                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4763            Slog.w(TAG, msg);
4764            throw new SecurityException(msg);
4765        }
4766
4767        synchronized(this) {
4768            if (mHeavyWeightProcess == null) {
4769                return;
4770            }
4771
4772            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4773            for (int i = 0; i < activities.size(); i++) {
4774                ActivityRecord r = activities.get(i);
4775                if (!r.finishing && r.isInStackLocked()) {
4776                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4777                            null, "finish-heavy", true);
4778                }
4779            }
4780
4781            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4782                    mHeavyWeightProcess.userId, 0));
4783            mHeavyWeightProcess = null;
4784        }
4785    }
4786
4787    @Override
4788    public void crashApplication(int uid, int initialPid, String packageName,
4789            String message) {
4790        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4791                != PackageManager.PERMISSION_GRANTED) {
4792            String msg = "Permission Denial: crashApplication() from pid="
4793                    + Binder.getCallingPid()
4794                    + ", uid=" + Binder.getCallingUid()
4795                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4796            Slog.w(TAG, msg);
4797            throw new SecurityException(msg);
4798        }
4799
4800        synchronized(this) {
4801            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4802        }
4803    }
4804
4805    @Override
4806    public final void finishSubActivity(IBinder token, String resultWho,
4807            int requestCode) {
4808        synchronized(this) {
4809            final long origId = Binder.clearCallingIdentity();
4810            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4811            if (r != null) {
4812                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4813            }
4814            Binder.restoreCallingIdentity(origId);
4815        }
4816    }
4817
4818    @Override
4819    public boolean finishActivityAffinity(IBinder token) {
4820        synchronized(this) {
4821            final long origId = Binder.clearCallingIdentity();
4822            try {
4823                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4824                if (r == null) {
4825                    return false;
4826                }
4827
4828                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4829                // can finish.
4830                final TaskRecord task = r.task;
4831                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4832                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4833                    mStackSupervisor.showLockTaskToast();
4834                    return false;
4835                }
4836                return task.stack.finishActivityAffinityLocked(r);
4837            } finally {
4838                Binder.restoreCallingIdentity(origId);
4839            }
4840        }
4841    }
4842
4843    @Override
4844    public void finishVoiceTask(IVoiceInteractionSession session) {
4845        synchronized (this) {
4846            final long origId = Binder.clearCallingIdentity();
4847            try {
4848                // TODO: VI Consider treating local voice interactions and voice tasks
4849                // differently here
4850                mStackSupervisor.finishVoiceTask(session);
4851            } finally {
4852                Binder.restoreCallingIdentity(origId);
4853            }
4854        }
4855
4856    }
4857
4858    @Override
4859    public boolean releaseActivityInstance(IBinder token) {
4860        synchronized(this) {
4861            final long origId = Binder.clearCallingIdentity();
4862            try {
4863                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4864                if (r == null) {
4865                    return false;
4866                }
4867                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4868            } finally {
4869                Binder.restoreCallingIdentity(origId);
4870            }
4871        }
4872    }
4873
4874    @Override
4875    public void releaseSomeActivities(IApplicationThread appInt) {
4876        synchronized(this) {
4877            final long origId = Binder.clearCallingIdentity();
4878            try {
4879                ProcessRecord app = getRecordForAppLocked(appInt);
4880                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4881            } finally {
4882                Binder.restoreCallingIdentity(origId);
4883            }
4884        }
4885    }
4886
4887    @Override
4888    public boolean willActivityBeVisible(IBinder token) {
4889        synchronized(this) {
4890            ActivityStack stack = ActivityRecord.getStackLocked(token);
4891            if (stack != null) {
4892                return stack.willActivityBeVisibleLocked(token);
4893            }
4894            return false;
4895        }
4896    }
4897
4898    @Override
4899    public void overridePendingTransition(IBinder token, String packageName,
4900            int enterAnim, int exitAnim) {
4901        synchronized(this) {
4902            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4903            if (self == null) {
4904                return;
4905            }
4906
4907            final long origId = Binder.clearCallingIdentity();
4908
4909            if (self.state == ActivityState.RESUMED
4910                    || self.state == ActivityState.PAUSING) {
4911                mWindowManager.overridePendingAppTransition(packageName,
4912                        enterAnim, exitAnim, null);
4913            }
4914
4915            Binder.restoreCallingIdentity(origId);
4916        }
4917    }
4918
4919    /**
4920     * Main function for removing an existing process from the activity manager
4921     * as a result of that process going away.  Clears out all connections
4922     * to the process.
4923     */
4924    private final void handleAppDiedLocked(ProcessRecord app,
4925            boolean restarting, boolean allowRestart) {
4926        int pid = app.pid;
4927        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4928        if (!kept && !restarting) {
4929            removeLruProcessLocked(app);
4930            if (pid > 0) {
4931                ProcessList.remove(pid);
4932            }
4933        }
4934
4935        if (mProfileProc == app) {
4936            clearProfilerLocked();
4937        }
4938
4939        // Remove this application's activities from active lists.
4940        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4941
4942        app.activities.clear();
4943
4944        if (app.instrumentationClass != null) {
4945            Slog.w(TAG, "Crash of app " + app.processName
4946                  + " running instrumentation " + app.instrumentationClass);
4947            Bundle info = new Bundle();
4948            info.putString("shortMsg", "Process crashed.");
4949            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4950        }
4951
4952        if (!restarting && hasVisibleActivities
4953                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4954            // If there was nothing to resume, and we are not already restarting this process, but
4955            // there is a visible activity that is hosted by the process...  then make sure all
4956            // visible activities are running, taking care of restarting this process.
4957            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4958        }
4959    }
4960
4961    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4962        IBinder threadBinder = thread.asBinder();
4963        // Find the application record.
4964        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4965            ProcessRecord rec = mLruProcesses.get(i);
4966            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4967                return i;
4968            }
4969        }
4970        return -1;
4971    }
4972
4973    final ProcessRecord getRecordForAppLocked(
4974            IApplicationThread thread) {
4975        if (thread == null) {
4976            return null;
4977        }
4978
4979        int appIndex = getLRURecordIndexForAppLocked(thread);
4980        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4981    }
4982
4983    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4984        // If there are no longer any background processes running,
4985        // and the app that died was not running instrumentation,
4986        // then tell everyone we are now low on memory.
4987        boolean haveBg = false;
4988        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4989            ProcessRecord rec = mLruProcesses.get(i);
4990            if (rec.thread != null
4991                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4992                haveBg = true;
4993                break;
4994            }
4995        }
4996
4997        if (!haveBg) {
4998            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4999            if (doReport) {
5000                long now = SystemClock.uptimeMillis();
5001                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5002                    doReport = false;
5003                } else {
5004                    mLastMemUsageReportTime = now;
5005                }
5006            }
5007            final ArrayList<ProcessMemInfo> memInfos
5008                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5009            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5010            long now = SystemClock.uptimeMillis();
5011            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5012                ProcessRecord rec = mLruProcesses.get(i);
5013                if (rec == dyingProc || rec.thread == null) {
5014                    continue;
5015                }
5016                if (doReport) {
5017                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5018                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5019                }
5020                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5021                    // The low memory report is overriding any current
5022                    // state for a GC request.  Make sure to do
5023                    // heavy/important/visible/foreground processes first.
5024                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5025                        rec.lastRequestedGc = 0;
5026                    } else {
5027                        rec.lastRequestedGc = rec.lastLowMemory;
5028                    }
5029                    rec.reportLowMemory = true;
5030                    rec.lastLowMemory = now;
5031                    mProcessesToGc.remove(rec);
5032                    addProcessToGcListLocked(rec);
5033                }
5034            }
5035            if (doReport) {
5036                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5037                mHandler.sendMessage(msg);
5038            }
5039            scheduleAppGcsLocked();
5040        }
5041    }
5042
5043    final void appDiedLocked(ProcessRecord app) {
5044       appDiedLocked(app, app.pid, app.thread, false);
5045    }
5046
5047    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5048            boolean fromBinderDied) {
5049        // First check if this ProcessRecord is actually active for the pid.
5050        synchronized (mPidsSelfLocked) {
5051            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5052            if (curProc != app) {
5053                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5054                return;
5055            }
5056        }
5057
5058        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5059        synchronized (stats) {
5060            stats.noteProcessDiedLocked(app.info.uid, pid);
5061        }
5062
5063        if (!app.killed) {
5064            if (!fromBinderDied) {
5065                Process.killProcessQuiet(pid);
5066            }
5067            killProcessGroup(app.uid, pid);
5068            app.killed = true;
5069        }
5070
5071        // Clean up already done if the process has been re-started.
5072        if (app.pid == pid && app.thread != null &&
5073                app.thread.asBinder() == thread.asBinder()) {
5074            boolean doLowMem = app.instrumentationClass == null;
5075            boolean doOomAdj = doLowMem;
5076            if (!app.killedByAm) {
5077                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5078                        + ") has died");
5079                mAllowLowerMemLevel = true;
5080            } else {
5081                // Note that we always want to do oom adj to update our state with the
5082                // new number of procs.
5083                mAllowLowerMemLevel = false;
5084                doLowMem = false;
5085            }
5086            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5087            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5088                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5089            handleAppDiedLocked(app, false, true);
5090
5091            if (doOomAdj) {
5092                updateOomAdjLocked();
5093            }
5094            if (doLowMem) {
5095                doLowMemReportIfNeededLocked(app);
5096            }
5097        } else if (app.pid != pid) {
5098            // A new process has already been started.
5099            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5100                    + ") has died and restarted (pid " + app.pid + ").");
5101            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5102        } else if (DEBUG_PROCESSES) {
5103            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5104                    + thread.asBinder());
5105        }
5106    }
5107
5108    /**
5109     * If a stack trace dump file is configured, dump process stack traces.
5110     * @param clearTraces causes the dump file to be erased prior to the new
5111     *    traces being written, if true; when false, the new traces will be
5112     *    appended to any existing file content.
5113     * @param firstPids of dalvik VM processes to dump stack traces for first
5114     * @param lastPids of dalvik VM processes to dump stack traces for last
5115     * @param nativeProcs optional list of native process names to dump stack crawls
5116     * @return file containing stack traces, or null if no dump file is configured
5117     */
5118    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5119            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5120        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5121        if (tracesPath == null || tracesPath.length() == 0) {
5122            return null;
5123        }
5124
5125        File tracesFile = new File(tracesPath);
5126        try {
5127            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5128            tracesFile.createNewFile();
5129            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5130        } catch (IOException e) {
5131            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5132            return null;
5133        }
5134
5135        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5136        return tracesFile;
5137    }
5138
5139    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5140            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5141        // Use a FileObserver to detect when traces finish writing.
5142        // The order of traces is considered important to maintain for legibility.
5143        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5144            @Override
5145            public synchronized void onEvent(int event, String path) { notify(); }
5146        };
5147
5148        try {
5149            observer.startWatching();
5150
5151            // First collect all of the stacks of the most important pids.
5152            if (firstPids != null) {
5153                try {
5154                    int num = firstPids.size();
5155                    for (int i = 0; i < num; i++) {
5156                        synchronized (observer) {
5157                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5158                                    + firstPids.get(i));
5159                            final long sime = SystemClock.elapsedRealtime();
5160                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5161                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5162                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5163                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5164                        }
5165                    }
5166                } catch (InterruptedException e) {
5167                    Slog.wtf(TAG, e);
5168                }
5169            }
5170
5171            // Next collect the stacks of the native pids
5172            if (nativeProcs != null) {
5173                int[] pids = Process.getPidsForCommands(nativeProcs);
5174                if (pids != null) {
5175                    for (int pid : pids) {
5176                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5177                        final long sime = SystemClock.elapsedRealtime();
5178                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5179                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5180                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5181                    }
5182                }
5183            }
5184
5185            // Lastly, measure CPU usage.
5186            if (processCpuTracker != null) {
5187                processCpuTracker.init();
5188                System.gc();
5189                processCpuTracker.update();
5190                try {
5191                    synchronized (processCpuTracker) {
5192                        processCpuTracker.wait(500); // measure over 1/2 second.
5193                    }
5194                } catch (InterruptedException e) {
5195                }
5196                processCpuTracker.update();
5197
5198                // We'll take the stack crawls of just the top apps using CPU.
5199                final int N = processCpuTracker.countWorkingStats();
5200                int numProcs = 0;
5201                for (int i=0; i<N && numProcs<5; i++) {
5202                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5203                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5204                        numProcs++;
5205                        try {
5206                            synchronized (observer) {
5207                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5208                                        + stats.pid);
5209                                final long stime = SystemClock.elapsedRealtime();
5210                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5211                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5212                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5213                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5214                            }
5215                        } catch (InterruptedException e) {
5216                            Slog.wtf(TAG, e);
5217                        }
5218                    } else if (DEBUG_ANR) {
5219                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5220                                + stats.pid);
5221                    }
5222                }
5223            }
5224        } finally {
5225            observer.stopWatching();
5226        }
5227    }
5228
5229    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5230        if (true || IS_USER_BUILD) {
5231            return;
5232        }
5233        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5234        if (tracesPath == null || tracesPath.length() == 0) {
5235            return;
5236        }
5237
5238        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5239        StrictMode.allowThreadDiskWrites();
5240        try {
5241            final File tracesFile = new File(tracesPath);
5242            final File tracesDir = tracesFile.getParentFile();
5243            final File tracesTmp = new File(tracesDir, "__tmp__");
5244            try {
5245                if (tracesFile.exists()) {
5246                    tracesTmp.delete();
5247                    tracesFile.renameTo(tracesTmp);
5248                }
5249                StringBuilder sb = new StringBuilder();
5250                Time tobj = new Time();
5251                tobj.set(System.currentTimeMillis());
5252                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5253                sb.append(": ");
5254                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5255                sb.append(" since ");
5256                sb.append(msg);
5257                FileOutputStream fos = new FileOutputStream(tracesFile);
5258                fos.write(sb.toString().getBytes());
5259                if (app == null) {
5260                    fos.write("\n*** No application process!".getBytes());
5261                }
5262                fos.close();
5263                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5264            } catch (IOException e) {
5265                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5266                return;
5267            }
5268
5269            if (app != null) {
5270                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5271                firstPids.add(app.pid);
5272                dumpStackTraces(tracesPath, firstPids, null, null, null);
5273            }
5274
5275            File lastTracesFile = null;
5276            File curTracesFile = null;
5277            for (int i=9; i>=0; i--) {
5278                String name = String.format(Locale.US, "slow%02d.txt", i);
5279                curTracesFile = new File(tracesDir, name);
5280                if (curTracesFile.exists()) {
5281                    if (lastTracesFile != null) {
5282                        curTracesFile.renameTo(lastTracesFile);
5283                    } else {
5284                        curTracesFile.delete();
5285                    }
5286                }
5287                lastTracesFile = curTracesFile;
5288            }
5289            tracesFile.renameTo(curTracesFile);
5290            if (tracesTmp.exists()) {
5291                tracesTmp.renameTo(tracesFile);
5292            }
5293        } finally {
5294            StrictMode.setThreadPolicy(oldPolicy);
5295        }
5296    }
5297
5298    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5299        if (!mLaunchWarningShown) {
5300            mLaunchWarningShown = true;
5301            mUiHandler.post(new Runnable() {
5302                @Override
5303                public void run() {
5304                    synchronized (ActivityManagerService.this) {
5305                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5306                        d.show();
5307                        mUiHandler.postDelayed(new Runnable() {
5308                            @Override
5309                            public void run() {
5310                                synchronized (ActivityManagerService.this) {
5311                                    d.dismiss();
5312                                    mLaunchWarningShown = false;
5313                                }
5314                            }
5315                        }, 4000);
5316                    }
5317                }
5318            });
5319        }
5320    }
5321
5322    @Override
5323    public boolean clearApplicationUserData(final String packageName,
5324            final IPackageDataObserver observer, int userId) {
5325        enforceNotIsolatedCaller("clearApplicationUserData");
5326        int uid = Binder.getCallingUid();
5327        int pid = Binder.getCallingPid();
5328        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5329                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5330
5331        final DevicePolicyManagerInternal dpmi = LocalServices
5332                .getService(DevicePolicyManagerInternal.class);
5333        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5334            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5335        }
5336
5337        long callingId = Binder.clearCallingIdentity();
5338        try {
5339            IPackageManager pm = AppGlobals.getPackageManager();
5340            int pkgUid = -1;
5341            synchronized(this) {
5342                try {
5343                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5344                } catch (RemoteException e) {
5345                }
5346                if (pkgUid == -1) {
5347                    Slog.w(TAG, "Invalid packageName: " + packageName);
5348                    if (observer != null) {
5349                        try {
5350                            observer.onRemoveCompleted(packageName, false);
5351                        } catch (RemoteException e) {
5352                            Slog.i(TAG, "Observer no longer exists.");
5353                        }
5354                    }
5355                    return false;
5356                }
5357                if (uid == pkgUid || checkComponentPermission(
5358                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5359                        pid, uid, -1, true)
5360                        == PackageManager.PERMISSION_GRANTED) {
5361                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5362                } else {
5363                    throw new SecurityException("PID " + pid + " does not have permission "
5364                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5365                                    + " of package " + packageName);
5366                }
5367
5368                // Remove all tasks match the cleared application package and user
5369                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5370                    final TaskRecord tr = mRecentTasks.get(i);
5371                    final String taskPackageName =
5372                            tr.getBaseIntent().getComponent().getPackageName();
5373                    if (tr.userId != userId) continue;
5374                    if (!taskPackageName.equals(packageName)) continue;
5375                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5376                }
5377            }
5378
5379            try {
5380                // Clear application user data
5381                pm.clearApplicationUserData(packageName, observer, userId);
5382
5383                synchronized(this) {
5384                    // Remove all permissions granted from/to this package
5385                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5386                }
5387
5388                // Remove all zen rules created by this package; revoke it's zen access.
5389                INotificationManager inm = NotificationManager.getService();
5390                inm.removeAutomaticZenRules(packageName);
5391                inm.setNotificationPolicyAccessGranted(packageName, false);
5392
5393                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5394                        Uri.fromParts("package", packageName, null));
5395                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5396                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5397                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5398                        null, null, 0, null, null, null, null, false, false, userId);
5399            } catch (RemoteException e) {
5400            }
5401        } finally {
5402            Binder.restoreCallingIdentity(callingId);
5403        }
5404        return true;
5405    }
5406
5407    @Override
5408    public void killBackgroundProcesses(final String packageName, int userId) {
5409        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5410                != PackageManager.PERMISSION_GRANTED &&
5411                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5412                        != PackageManager.PERMISSION_GRANTED) {
5413            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5414                    + Binder.getCallingPid()
5415                    + ", uid=" + Binder.getCallingUid()
5416                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5417            Slog.w(TAG, msg);
5418            throw new SecurityException(msg);
5419        }
5420
5421        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5422                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5423        long callingId = Binder.clearCallingIdentity();
5424        try {
5425            IPackageManager pm = AppGlobals.getPackageManager();
5426            synchronized(this) {
5427                int appId = -1;
5428                try {
5429                    appId = UserHandle.getAppId(
5430                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5431                } catch (RemoteException e) {
5432                }
5433                if (appId == -1) {
5434                    Slog.w(TAG, "Invalid packageName: " + packageName);
5435                    return;
5436                }
5437                killPackageProcessesLocked(packageName, appId, userId,
5438                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5439            }
5440        } finally {
5441            Binder.restoreCallingIdentity(callingId);
5442        }
5443    }
5444
5445    @Override
5446    public void killAllBackgroundProcesses() {
5447        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5448                != PackageManager.PERMISSION_GRANTED) {
5449            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5450                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5451                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5452            Slog.w(TAG, msg);
5453            throw new SecurityException(msg);
5454        }
5455
5456        final long callingId = Binder.clearCallingIdentity();
5457        try {
5458            synchronized (this) {
5459                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5460                final int NP = mProcessNames.getMap().size();
5461                for (int ip = 0; ip < NP; ip++) {
5462                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5463                    final int NA = apps.size();
5464                    for (int ia = 0; ia < NA; ia++) {
5465                        final ProcessRecord app = apps.valueAt(ia);
5466                        if (app.persistent) {
5467                            // We don't kill persistent processes.
5468                            continue;
5469                        }
5470                        if (app.removed) {
5471                            procs.add(app);
5472                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5473                            app.removed = true;
5474                            procs.add(app);
5475                        }
5476                    }
5477                }
5478
5479                final int N = procs.size();
5480                for (int i = 0; i < N; i++) {
5481                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5482                }
5483
5484                mAllowLowerMemLevel = true;
5485
5486                updateOomAdjLocked();
5487                doLowMemReportIfNeededLocked(null);
5488            }
5489        } finally {
5490            Binder.restoreCallingIdentity(callingId);
5491        }
5492    }
5493
5494    /**
5495     * Kills all background processes, except those matching any of the
5496     * specified properties.
5497     *
5498     * @param minTargetSdk the target SDK version at or above which to preserve
5499     *                     processes, or {@code -1} to ignore the target SDK
5500     * @param maxProcState the process state at or below which to preserve
5501     *                     processes, or {@code -1} to ignore the process state
5502     */
5503    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5504        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5505                != PackageManager.PERMISSION_GRANTED) {
5506            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5507                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5508                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5509            Slog.w(TAG, msg);
5510            throw new SecurityException(msg);
5511        }
5512
5513        final long callingId = Binder.clearCallingIdentity();
5514        try {
5515            synchronized (this) {
5516                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5517                final int NP = mProcessNames.getMap().size();
5518                for (int ip = 0; ip < NP; ip++) {
5519                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5520                    final int NA = apps.size();
5521                    for (int ia = 0; ia < NA; ia++) {
5522                        final ProcessRecord app = apps.valueAt(ia);
5523                        if (app.removed) {
5524                            procs.add(app);
5525                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5526                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5527                            app.removed = true;
5528                            procs.add(app);
5529                        }
5530                    }
5531                }
5532
5533                final int N = procs.size();
5534                for (int i = 0; i < N; i++) {
5535                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5536                }
5537            }
5538        } finally {
5539            Binder.restoreCallingIdentity(callingId);
5540        }
5541    }
5542
5543    @Override
5544    public void forceStopPackage(final String packageName, int userId) {
5545        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5546                != PackageManager.PERMISSION_GRANTED) {
5547            String msg = "Permission Denial: forceStopPackage() from pid="
5548                    + Binder.getCallingPid()
5549                    + ", uid=" + Binder.getCallingUid()
5550                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5551            Slog.w(TAG, msg);
5552            throw new SecurityException(msg);
5553        }
5554        final int callingPid = Binder.getCallingPid();
5555        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5556                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5557        long callingId = Binder.clearCallingIdentity();
5558        try {
5559            IPackageManager pm = AppGlobals.getPackageManager();
5560            synchronized(this) {
5561                int[] users = userId == UserHandle.USER_ALL
5562                        ? mUserController.getUsers() : new int[] { userId };
5563                for (int user : users) {
5564                    int pkgUid = -1;
5565                    try {
5566                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5567                                user);
5568                    } catch (RemoteException e) {
5569                    }
5570                    if (pkgUid == -1) {
5571                        Slog.w(TAG, "Invalid packageName: " + packageName);
5572                        continue;
5573                    }
5574                    try {
5575                        pm.setPackageStoppedState(packageName, true, user);
5576                    } catch (RemoteException e) {
5577                    } catch (IllegalArgumentException e) {
5578                        Slog.w(TAG, "Failed trying to unstop package "
5579                                + packageName + ": " + e);
5580                    }
5581                    if (mUserController.isUserRunningLocked(user, 0)) {
5582                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5583                    }
5584                }
5585            }
5586        } finally {
5587            Binder.restoreCallingIdentity(callingId);
5588        }
5589    }
5590
5591    @Override
5592    public void addPackageDependency(String packageName) {
5593        synchronized (this) {
5594            int callingPid = Binder.getCallingPid();
5595            if (callingPid == Process.myPid()) {
5596                //  Yeah, um, no.
5597                return;
5598            }
5599            ProcessRecord proc;
5600            synchronized (mPidsSelfLocked) {
5601                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5602            }
5603            if (proc != null) {
5604                if (proc.pkgDeps == null) {
5605                    proc.pkgDeps = new ArraySet<String>(1);
5606                }
5607                proc.pkgDeps.add(packageName);
5608            }
5609        }
5610    }
5611
5612    /*
5613     * The pkg name and app id have to be specified.
5614     */
5615    @Override
5616    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5617        if (pkg == null) {
5618            return;
5619        }
5620        // Make sure the uid is valid.
5621        if (appid < 0) {
5622            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5623            return;
5624        }
5625        int callerUid = Binder.getCallingUid();
5626        // Only the system server can kill an application
5627        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5628            // Post an aysnc message to kill the application
5629            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5630            msg.arg1 = appid;
5631            msg.arg2 = 0;
5632            Bundle bundle = new Bundle();
5633            bundle.putString("pkg", pkg);
5634            bundle.putString("reason", reason);
5635            msg.obj = bundle;
5636            mHandler.sendMessage(msg);
5637        } else {
5638            throw new SecurityException(callerUid + " cannot kill pkg: " +
5639                    pkg);
5640        }
5641    }
5642
5643    @Override
5644    public void closeSystemDialogs(String reason) {
5645        enforceNotIsolatedCaller("closeSystemDialogs");
5646
5647        final int pid = Binder.getCallingPid();
5648        final int uid = Binder.getCallingUid();
5649        final long origId = Binder.clearCallingIdentity();
5650        try {
5651            synchronized (this) {
5652                // Only allow this from foreground processes, so that background
5653                // applications can't abuse it to prevent system UI from being shown.
5654                if (uid >= Process.FIRST_APPLICATION_UID) {
5655                    ProcessRecord proc;
5656                    synchronized (mPidsSelfLocked) {
5657                        proc = mPidsSelfLocked.get(pid);
5658                    }
5659                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5660                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5661                                + " from background process " + proc);
5662                        return;
5663                    }
5664                }
5665                closeSystemDialogsLocked(reason);
5666            }
5667        } finally {
5668            Binder.restoreCallingIdentity(origId);
5669        }
5670    }
5671
5672    void closeSystemDialogsLocked(String reason) {
5673        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5674        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5675                | Intent.FLAG_RECEIVER_FOREGROUND);
5676        if (reason != null) {
5677            intent.putExtra("reason", reason);
5678        }
5679        mWindowManager.closeSystemDialogs(reason);
5680
5681        mStackSupervisor.closeSystemDialogsLocked();
5682
5683        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5684                AppOpsManager.OP_NONE, null, false, false,
5685                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5686    }
5687
5688    @Override
5689    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5690        enforceNotIsolatedCaller("getProcessMemoryInfo");
5691        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5692        for (int i=pids.length-1; i>=0; i--) {
5693            ProcessRecord proc;
5694            int oomAdj;
5695            synchronized (this) {
5696                synchronized (mPidsSelfLocked) {
5697                    proc = mPidsSelfLocked.get(pids[i]);
5698                    oomAdj = proc != null ? proc.setAdj : 0;
5699                }
5700            }
5701            infos[i] = new Debug.MemoryInfo();
5702            Debug.getMemoryInfo(pids[i], infos[i]);
5703            if (proc != null) {
5704                synchronized (this) {
5705                    if (proc.thread != null && proc.setAdj == oomAdj) {
5706                        // Record this for posterity if the process has been stable.
5707                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5708                                infos[i].getTotalUss(), false, proc.pkgList);
5709                    }
5710                }
5711            }
5712        }
5713        return infos;
5714    }
5715
5716    @Override
5717    public long[] getProcessPss(int[] pids) {
5718        enforceNotIsolatedCaller("getProcessPss");
5719        long[] pss = new long[pids.length];
5720        for (int i=pids.length-1; i>=0; i--) {
5721            ProcessRecord proc;
5722            int oomAdj;
5723            synchronized (this) {
5724                synchronized (mPidsSelfLocked) {
5725                    proc = mPidsSelfLocked.get(pids[i]);
5726                    oomAdj = proc != null ? proc.setAdj : 0;
5727                }
5728            }
5729            long[] tmpUss = new long[1];
5730            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5731            if (proc != null) {
5732                synchronized (this) {
5733                    if (proc.thread != null && proc.setAdj == oomAdj) {
5734                        // Record this for posterity if the process has been stable.
5735                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5736                    }
5737                }
5738            }
5739        }
5740        return pss;
5741    }
5742
5743    @Override
5744    public void killApplicationProcess(String processName, int uid) {
5745        if (processName == null) {
5746            return;
5747        }
5748
5749        int callerUid = Binder.getCallingUid();
5750        // Only the system server can kill an application
5751        if (callerUid == Process.SYSTEM_UID) {
5752            synchronized (this) {
5753                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5754                if (app != null && app.thread != null) {
5755                    try {
5756                        app.thread.scheduleSuicide();
5757                    } catch (RemoteException e) {
5758                        // If the other end already died, then our work here is done.
5759                    }
5760                } else {
5761                    Slog.w(TAG, "Process/uid not found attempting kill of "
5762                            + processName + " / " + uid);
5763                }
5764            }
5765        } else {
5766            throw new SecurityException(callerUid + " cannot kill app process: " +
5767                    processName);
5768        }
5769    }
5770
5771    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5772        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5773                false, true, false, false, UserHandle.getUserId(uid), reason);
5774        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5775                Uri.fromParts("package", packageName, null));
5776        if (!mProcessesReady) {
5777            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5778                    | Intent.FLAG_RECEIVER_FOREGROUND);
5779        }
5780        intent.putExtra(Intent.EXTRA_UID, uid);
5781        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5782        broadcastIntentLocked(null, null, intent,
5783                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5784                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5785    }
5786
5787
5788    private final boolean killPackageProcessesLocked(String packageName, int appId,
5789            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5790            boolean doit, boolean evenPersistent, String reason) {
5791        ArrayList<ProcessRecord> procs = new ArrayList<>();
5792
5793        // Remove all processes this package may have touched: all with the
5794        // same UID (except for the system or root user), and all whose name
5795        // matches the package name.
5796        final int NP = mProcessNames.getMap().size();
5797        for (int ip=0; ip<NP; ip++) {
5798            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5799            final int NA = apps.size();
5800            for (int ia=0; ia<NA; ia++) {
5801                ProcessRecord app = apps.valueAt(ia);
5802                if (app.persistent && !evenPersistent) {
5803                    // we don't kill persistent processes
5804                    continue;
5805                }
5806                if (app.removed) {
5807                    if (doit) {
5808                        procs.add(app);
5809                    }
5810                    continue;
5811                }
5812
5813                // Skip process if it doesn't meet our oom adj requirement.
5814                if (app.setAdj < minOomAdj) {
5815                    continue;
5816                }
5817
5818                // If no package is specified, we call all processes under the
5819                // give user id.
5820                if (packageName == null) {
5821                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5822                        continue;
5823                    }
5824                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5825                        continue;
5826                    }
5827                // Package has been specified, we want to hit all processes
5828                // that match it.  We need to qualify this by the processes
5829                // that are running under the specified app and user ID.
5830                } else {
5831                    final boolean isDep = app.pkgDeps != null
5832                            && app.pkgDeps.contains(packageName);
5833                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5834                        continue;
5835                    }
5836                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5837                        continue;
5838                    }
5839                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5840                        continue;
5841                    }
5842                }
5843
5844                // Process has passed all conditions, kill it!
5845                if (!doit) {
5846                    return true;
5847                }
5848                app.removed = true;
5849                procs.add(app);
5850            }
5851        }
5852
5853        int N = procs.size();
5854        for (int i=0; i<N; i++) {
5855            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5856        }
5857        updateOomAdjLocked();
5858        return N > 0;
5859    }
5860
5861    private void cleanupDisabledPackageComponentsLocked(
5862            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5863
5864        Set<String> disabledClasses = null;
5865        boolean packageDisabled = false;
5866        IPackageManager pm = AppGlobals.getPackageManager();
5867
5868        if (changedClasses == null) {
5869            // Nothing changed...
5870            return;
5871        }
5872
5873        // Determine enable/disable state of the package and its components.
5874        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5875        for (int i = changedClasses.length - 1; i >= 0; i--) {
5876            final String changedClass = changedClasses[i];
5877
5878            if (changedClass.equals(packageName)) {
5879                try {
5880                    // Entire package setting changed
5881                    enabled = pm.getApplicationEnabledSetting(packageName,
5882                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5883                } catch (Exception e) {
5884                    // No such package/component; probably racing with uninstall.  In any
5885                    // event it means we have nothing further to do here.
5886                    return;
5887                }
5888                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5889                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5890                if (packageDisabled) {
5891                    // Entire package is disabled.
5892                    // No need to continue to check component states.
5893                    disabledClasses = null;
5894                    break;
5895                }
5896            } else {
5897                try {
5898                    enabled = pm.getComponentEnabledSetting(
5899                            new ComponentName(packageName, changedClass),
5900                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5901                } catch (Exception e) {
5902                    // As above, probably racing with uninstall.
5903                    return;
5904                }
5905                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5906                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5907                    if (disabledClasses == null) {
5908                        disabledClasses = new ArraySet<>(changedClasses.length);
5909                    }
5910                    disabledClasses.add(changedClass);
5911                }
5912            }
5913        }
5914
5915        if (!packageDisabled && disabledClasses == null) {
5916            // Nothing to do here...
5917            return;
5918        }
5919
5920        // Clean-up disabled activities.
5921        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5922                packageName, disabledClasses, true, false, userId) && mBooted) {
5923            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5924            mStackSupervisor.scheduleIdleLocked();
5925        }
5926
5927        // Clean-up disabled tasks
5928        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5929
5930        // Clean-up disabled services.
5931        mServices.bringDownDisabledPackageServicesLocked(
5932                packageName, disabledClasses, userId, false, killProcess, true);
5933
5934        // Clean-up disabled providers.
5935        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5936        mProviderMap.collectPackageProvidersLocked(
5937                packageName, disabledClasses, true, false, userId, providers);
5938        for (int i = providers.size() - 1; i >= 0; i--) {
5939            removeDyingProviderLocked(null, providers.get(i), true);
5940        }
5941
5942        // Clean-up disabled broadcast receivers.
5943        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5944            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5945                    packageName, disabledClasses, userId, true);
5946        }
5947
5948    }
5949
5950    final boolean forceStopPackageLocked(String packageName, int appId,
5951            boolean callerWillRestart, boolean purgeCache, boolean doit,
5952            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5953        int i;
5954
5955        if (userId == UserHandle.USER_ALL && packageName == null) {
5956            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5957        }
5958
5959        if (appId < 0 && packageName != null) {
5960            try {
5961                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5962                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5963            } catch (RemoteException e) {
5964            }
5965        }
5966
5967        if (doit) {
5968            if (packageName != null) {
5969                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5970                        + " user=" + userId + ": " + reason);
5971            } else {
5972                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5973            }
5974
5975            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5976        }
5977
5978        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5979                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5980                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5981
5982        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5983                packageName, null, doit, evenPersistent, userId)) {
5984            if (!doit) {
5985                return true;
5986            }
5987            didSomething = true;
5988        }
5989
5990        if (mServices.bringDownDisabledPackageServicesLocked(
5991                packageName, null, userId, evenPersistent, true, doit)) {
5992            if (!doit) {
5993                return true;
5994            }
5995            didSomething = true;
5996        }
5997
5998        if (packageName == null) {
5999            // Remove all sticky broadcasts from this user.
6000            mStickyBroadcasts.remove(userId);
6001        }
6002
6003        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6004        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6005                userId, providers)) {
6006            if (!doit) {
6007                return true;
6008            }
6009            didSomething = true;
6010        }
6011        for (i = providers.size() - 1; i >= 0; i--) {
6012            removeDyingProviderLocked(null, providers.get(i), true);
6013        }
6014
6015        // Remove transient permissions granted from/to this package/user
6016        removeUriPermissionsForPackageLocked(packageName, userId, false);
6017
6018        if (doit) {
6019            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6020                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6021                        packageName, null, userId, doit);
6022            }
6023        }
6024
6025        if (packageName == null || uninstalling) {
6026            // Remove pending intents.  For now we only do this when force
6027            // stopping users, because we have some problems when doing this
6028            // for packages -- app widgets are not currently cleaned up for
6029            // such packages, so they can be left with bad pending intents.
6030            if (mIntentSenderRecords.size() > 0) {
6031                Iterator<WeakReference<PendingIntentRecord>> it
6032                        = mIntentSenderRecords.values().iterator();
6033                while (it.hasNext()) {
6034                    WeakReference<PendingIntentRecord> wpir = it.next();
6035                    if (wpir == null) {
6036                        it.remove();
6037                        continue;
6038                    }
6039                    PendingIntentRecord pir = wpir.get();
6040                    if (pir == null) {
6041                        it.remove();
6042                        continue;
6043                    }
6044                    if (packageName == null) {
6045                        // Stopping user, remove all objects for the user.
6046                        if (pir.key.userId != userId) {
6047                            // Not the same user, skip it.
6048                            continue;
6049                        }
6050                    } else {
6051                        if (UserHandle.getAppId(pir.uid) != appId) {
6052                            // Different app id, skip it.
6053                            continue;
6054                        }
6055                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6056                            // Different user, skip it.
6057                            continue;
6058                        }
6059                        if (!pir.key.packageName.equals(packageName)) {
6060                            // Different package, skip it.
6061                            continue;
6062                        }
6063                    }
6064                    if (!doit) {
6065                        return true;
6066                    }
6067                    didSomething = true;
6068                    it.remove();
6069                    pir.canceled = true;
6070                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6071                        pir.key.activity.pendingResults.remove(pir.ref);
6072                    }
6073                }
6074            }
6075        }
6076
6077        if (doit) {
6078            if (purgeCache && packageName != null) {
6079                AttributeCache ac = AttributeCache.instance();
6080                if (ac != null) {
6081                    ac.removePackage(packageName);
6082                }
6083            }
6084            if (mBooted) {
6085                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6086                mStackSupervisor.scheduleIdleLocked();
6087            }
6088        }
6089
6090        return didSomething;
6091    }
6092
6093    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6094        ProcessRecord old = mProcessNames.remove(name, uid);
6095        if (old != null) {
6096            old.uidRecord.numProcs--;
6097            if (old.uidRecord.numProcs == 0) {
6098                // No more processes using this uid, tell clients it is gone.
6099                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6100                        "No more processes in " + old.uidRecord);
6101                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6102                mActiveUids.remove(uid);
6103                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6104            }
6105            old.uidRecord = null;
6106        }
6107        mIsolatedProcesses.remove(uid);
6108        return old;
6109    }
6110
6111    private final void addProcessNameLocked(ProcessRecord proc) {
6112        // We shouldn't already have a process under this name, but just in case we
6113        // need to clean up whatever may be there now.
6114        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6115        if (old == proc && proc.persistent) {
6116            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6117            Slog.w(TAG, "Re-adding persistent process " + proc);
6118        } else if (old != null) {
6119            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6120        }
6121        UidRecord uidRec = mActiveUids.get(proc.uid);
6122        if (uidRec == null) {
6123            uidRec = new UidRecord(proc.uid);
6124            // This is the first appearance of the uid, report it now!
6125            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6126                    "Creating new process uid: " + uidRec);
6127            mActiveUids.put(proc.uid, uidRec);
6128            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6129            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6130        }
6131        proc.uidRecord = uidRec;
6132        uidRec.numProcs++;
6133        mProcessNames.put(proc.processName, proc.uid, proc);
6134        if (proc.isolated) {
6135            mIsolatedProcesses.put(proc.uid, proc);
6136        }
6137    }
6138
6139    boolean removeProcessLocked(ProcessRecord app,
6140            boolean callerWillRestart, boolean allowRestart, String reason) {
6141        final String name = app.processName;
6142        final int uid = app.uid;
6143        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6144            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6145
6146        removeProcessNameLocked(name, uid);
6147        if (mHeavyWeightProcess == app) {
6148            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6149                    mHeavyWeightProcess.userId, 0));
6150            mHeavyWeightProcess = null;
6151        }
6152        boolean needRestart = false;
6153        if (app.pid > 0 && app.pid != MY_PID) {
6154            int pid = app.pid;
6155            synchronized (mPidsSelfLocked) {
6156                mPidsSelfLocked.remove(pid);
6157                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6158            }
6159            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6160            if (app.isolated) {
6161                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6162            }
6163            boolean willRestart = false;
6164            if (app.persistent && !app.isolated) {
6165                if (!callerWillRestart) {
6166                    willRestart = true;
6167                } else {
6168                    needRestart = true;
6169                }
6170            }
6171            app.kill(reason, true);
6172            handleAppDiedLocked(app, willRestart, allowRestart);
6173            if (willRestart) {
6174                removeLruProcessLocked(app);
6175                addAppLocked(app.info, false, null /* ABI override */);
6176            }
6177        } else {
6178            mRemovedProcesses.add(app);
6179        }
6180
6181        return needRestart;
6182    }
6183
6184    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6185        cleanupAppInLaunchingProvidersLocked(app, true);
6186        removeProcessLocked(app, false, true, "timeout publishing content providers");
6187    }
6188
6189    private final void processStartTimedOutLocked(ProcessRecord app) {
6190        final int pid = app.pid;
6191        boolean gone = false;
6192        synchronized (mPidsSelfLocked) {
6193            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6194            if (knownApp != null && knownApp.thread == null) {
6195                mPidsSelfLocked.remove(pid);
6196                gone = true;
6197            }
6198        }
6199
6200        if (gone) {
6201            Slog.w(TAG, "Process " + app + " failed to attach");
6202            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6203                    pid, app.uid, app.processName);
6204            removeProcessNameLocked(app.processName, app.uid);
6205            if (mHeavyWeightProcess == app) {
6206                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6207                        mHeavyWeightProcess.userId, 0));
6208                mHeavyWeightProcess = null;
6209            }
6210            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6211            if (app.isolated) {
6212                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6213            }
6214            // Take care of any launching providers waiting for this process.
6215            cleanupAppInLaunchingProvidersLocked(app, true);
6216            // Take care of any services that are waiting for the process.
6217            mServices.processStartTimedOutLocked(app);
6218            app.kill("start timeout", true);
6219            removeLruProcessLocked(app);
6220            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6221                Slog.w(TAG, "Unattached app died before backup, skipping");
6222                try {
6223                    IBackupManager bm = IBackupManager.Stub.asInterface(
6224                            ServiceManager.getService(Context.BACKUP_SERVICE));
6225                    bm.agentDisconnected(app.info.packageName);
6226                } catch (RemoteException e) {
6227                    // Can't happen; the backup manager is local
6228                }
6229            }
6230            if (isPendingBroadcastProcessLocked(pid)) {
6231                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6232                skipPendingBroadcastLocked(pid);
6233            }
6234        } else {
6235            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6236        }
6237    }
6238
6239    private final boolean attachApplicationLocked(IApplicationThread thread,
6240            int pid) {
6241
6242        // Find the application record that is being attached...  either via
6243        // the pid if we are running in multiple processes, or just pull the
6244        // next app record if we are emulating process with anonymous threads.
6245        ProcessRecord app;
6246        if (pid != MY_PID && pid >= 0) {
6247            synchronized (mPidsSelfLocked) {
6248                app = mPidsSelfLocked.get(pid);
6249            }
6250        } else {
6251            app = null;
6252        }
6253
6254        if (app == null) {
6255            Slog.w(TAG, "No pending application record for pid " + pid
6256                    + " (IApplicationThread " + thread + "); dropping process");
6257            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6258            if (pid > 0 && pid != MY_PID) {
6259                Process.killProcessQuiet(pid);
6260                //TODO: killProcessGroup(app.info.uid, pid);
6261            } else {
6262                try {
6263                    thread.scheduleExit();
6264                } catch (Exception e) {
6265                    // Ignore exceptions.
6266                }
6267            }
6268            return false;
6269        }
6270
6271        // If this application record is still attached to a previous
6272        // process, clean it up now.
6273        if (app.thread != null) {
6274            handleAppDiedLocked(app, true, true);
6275        }
6276
6277        // Tell the process all about itself.
6278
6279        if (DEBUG_ALL) Slog.v(
6280                TAG, "Binding process pid " + pid + " to record " + app);
6281
6282        final String processName = app.processName;
6283        try {
6284            AppDeathRecipient adr = new AppDeathRecipient(
6285                    app, pid, thread);
6286            thread.asBinder().linkToDeath(adr, 0);
6287            app.deathRecipient = adr;
6288        } catch (RemoteException e) {
6289            app.resetPackageList(mProcessStats);
6290            startProcessLocked(app, "link fail", processName);
6291            return false;
6292        }
6293
6294        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6295
6296        app.makeActive(thread, mProcessStats);
6297        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6298        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6299        app.forcingToForeground = null;
6300        updateProcessForegroundLocked(app, false, false);
6301        app.hasShownUi = false;
6302        app.debugging = false;
6303        app.cached = false;
6304        app.killedByAm = false;
6305        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6306
6307        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6308
6309        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6310        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6311
6312        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6313            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6314            msg.obj = app;
6315            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6316        }
6317
6318        if (!normalMode) {
6319            Slog.i(TAG, "Launching preboot mode app: " + app);
6320        }
6321
6322        if (DEBUG_ALL) Slog.v(
6323            TAG, "New app record " + app
6324            + " thread=" + thread.asBinder() + " pid=" + pid);
6325        try {
6326            int testMode = IApplicationThread.DEBUG_OFF;
6327            if (mDebugApp != null && mDebugApp.equals(processName)) {
6328                testMode = mWaitForDebugger
6329                    ? IApplicationThread.DEBUG_WAIT
6330                    : IApplicationThread.DEBUG_ON;
6331                app.debugging = true;
6332                if (mDebugTransient) {
6333                    mDebugApp = mOrigDebugApp;
6334                    mWaitForDebugger = mOrigWaitForDebugger;
6335                }
6336            }
6337            String profileFile = app.instrumentationProfileFile;
6338            ParcelFileDescriptor profileFd = null;
6339            int samplingInterval = 0;
6340            boolean profileAutoStop = false;
6341            if (mProfileApp != null && mProfileApp.equals(processName)) {
6342                mProfileProc = app;
6343                profileFile = mProfileFile;
6344                profileFd = mProfileFd;
6345                samplingInterval = mSamplingInterval;
6346                profileAutoStop = mAutoStopProfiler;
6347            }
6348            boolean enableTrackAllocation = false;
6349            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6350                enableTrackAllocation = true;
6351                mTrackAllocationApp = null;
6352            }
6353
6354            // If the app is being launched for restore or full backup, set it up specially
6355            boolean isRestrictedBackupMode = false;
6356            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6357                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6358                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6359                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6360                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6361            }
6362
6363            notifyPackageUse(app.instrumentationInfo != null
6364                    ? app.instrumentationInfo.packageName
6365                    : app.info.packageName);
6366            if (app.instrumentationClass != null) {
6367                notifyPackageUse(app.instrumentationClass.getPackageName());
6368            }
6369            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6370                    + processName + " with config " + mConfiguration);
6371            ApplicationInfo appInfo = app.instrumentationInfo != null
6372                    ? app.instrumentationInfo : app.info;
6373            app.compat = compatibilityInfoForPackageLocked(appInfo);
6374            if (profileFd != null) {
6375                profileFd = profileFd.dup();
6376            }
6377            ProfilerInfo profilerInfo = profileFile == null ? null
6378                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6379            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6380                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6381                    app.instrumentationUiAutomationConnection, testMode,
6382                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6383                    isRestrictedBackupMode || !normalMode, app.persistent,
6384                    new Configuration(mConfiguration), app.compat,
6385                    getCommonServicesLocked(app.isolated),
6386                    mCoreSettingsObserver.getCoreSettingsLocked());
6387            updateLruProcessLocked(app, false, null);
6388            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6389        } catch (Exception e) {
6390            // todo: Yikes!  What should we do?  For now we will try to
6391            // start another process, but that could easily get us in
6392            // an infinite loop of restarting processes...
6393            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6394
6395            app.resetPackageList(mProcessStats);
6396            app.unlinkDeathRecipient();
6397            startProcessLocked(app, "bind fail", processName);
6398            return false;
6399        }
6400
6401        // Remove this record from the list of starting applications.
6402        mPersistentStartingProcesses.remove(app);
6403        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6404                "Attach application locked removing on hold: " + app);
6405        mProcessesOnHold.remove(app);
6406
6407        boolean badApp = false;
6408        boolean didSomething = false;
6409
6410        // See if the top visible activity is waiting to run in this process...
6411        if (normalMode) {
6412            try {
6413                if (mStackSupervisor.attachApplicationLocked(app)) {
6414                    didSomething = true;
6415                }
6416            } catch (Exception e) {
6417                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6418                badApp = true;
6419            }
6420        }
6421
6422        // Find any services that should be running in this process...
6423        if (!badApp) {
6424            try {
6425                didSomething |= mServices.attachApplicationLocked(app, processName);
6426            } catch (Exception e) {
6427                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6428                badApp = true;
6429            }
6430        }
6431
6432        // Check if a next-broadcast receiver is in this process...
6433        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6434            try {
6435                didSomething |= sendPendingBroadcastsLocked(app);
6436            } catch (Exception e) {
6437                // If the app died trying to launch the receiver we declare it 'bad'
6438                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6439                badApp = true;
6440            }
6441        }
6442
6443        // Check whether the next backup agent is in this process...
6444        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6445            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6446                    "New app is backup target, launching agent for " + app);
6447            notifyPackageUse(mBackupTarget.appInfo.packageName);
6448            try {
6449                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6450                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6451                        mBackupTarget.backupMode);
6452            } catch (Exception e) {
6453                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6454                badApp = true;
6455            }
6456        }
6457
6458        if (badApp) {
6459            app.kill("error during init", true);
6460            handleAppDiedLocked(app, false, true);
6461            return false;
6462        }
6463
6464        if (!didSomething) {
6465            updateOomAdjLocked();
6466        }
6467
6468        return true;
6469    }
6470
6471    @Override
6472    public final void attachApplication(IApplicationThread thread) {
6473        synchronized (this) {
6474            int callingPid = Binder.getCallingPid();
6475            final long origId = Binder.clearCallingIdentity();
6476            attachApplicationLocked(thread, callingPid);
6477            Binder.restoreCallingIdentity(origId);
6478        }
6479    }
6480
6481    @Override
6482    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6483        final long origId = Binder.clearCallingIdentity();
6484        synchronized (this) {
6485            ActivityStack stack = ActivityRecord.getStackLocked(token);
6486            if (stack != null) {
6487                ActivityRecord r =
6488                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6489                if (stopProfiling) {
6490                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6491                        try {
6492                            mProfileFd.close();
6493                        } catch (IOException e) {
6494                        }
6495                        clearProfilerLocked();
6496                    }
6497                }
6498            }
6499        }
6500        Binder.restoreCallingIdentity(origId);
6501    }
6502
6503    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6504        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6505                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6506    }
6507
6508    void enableScreenAfterBoot() {
6509        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6510                SystemClock.uptimeMillis());
6511        mWindowManager.enableScreenAfterBoot();
6512
6513        synchronized (this) {
6514            updateEventDispatchingLocked();
6515        }
6516    }
6517
6518    @Override
6519    public void showBootMessage(final CharSequence msg, final boolean always) {
6520        if (Binder.getCallingUid() != Process.myUid()) {
6521            // These days only the core system can call this, so apps can't get in
6522            // the way of what we show about running them.
6523        }
6524        mWindowManager.showBootMessage(msg, always);
6525    }
6526
6527    @Override
6528    public void keyguardWaitingForActivityDrawn() {
6529        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6530        final long token = Binder.clearCallingIdentity();
6531        try {
6532            synchronized (this) {
6533                if (DEBUG_LOCKSCREEN) logLockScreen("");
6534                mWindowManager.keyguardWaitingForActivityDrawn();
6535                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6536                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6537                    updateSleepIfNeededLocked();
6538                }
6539            }
6540        } finally {
6541            Binder.restoreCallingIdentity(token);
6542        }
6543    }
6544
6545    @Override
6546    public void keyguardGoingAway(int flags) {
6547        enforceNotIsolatedCaller("keyguardGoingAway");
6548        final long token = Binder.clearCallingIdentity();
6549        try {
6550            synchronized (this) {
6551                if (DEBUG_LOCKSCREEN) logLockScreen("");
6552                mWindowManager.keyguardGoingAway(flags);
6553                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6554                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6555                    updateSleepIfNeededLocked();
6556
6557                    // Some stack visibility might change (e.g. docked stack)
6558                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6559                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6560                }
6561            }
6562        } finally {
6563            Binder.restoreCallingIdentity(token);
6564        }
6565    }
6566
6567    final void finishBooting() {
6568        synchronized (this) {
6569            if (!mBootAnimationComplete) {
6570                mCallFinishBooting = true;
6571                return;
6572            }
6573            mCallFinishBooting = false;
6574        }
6575
6576        ArraySet<String> completedIsas = new ArraySet<String>();
6577        for (String abi : Build.SUPPORTED_ABIS) {
6578            Process.establishZygoteConnectionForAbi(abi);
6579            final String instructionSet = VMRuntime.getInstructionSet(abi);
6580            if (!completedIsas.contains(instructionSet)) {
6581                try {
6582                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6583                } catch (InstallerException e) {
6584                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6585                }
6586                completedIsas.add(instructionSet);
6587            }
6588        }
6589
6590        IntentFilter pkgFilter = new IntentFilter();
6591        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6592        pkgFilter.addDataScheme("package");
6593        mContext.registerReceiver(new BroadcastReceiver() {
6594            @Override
6595            public void onReceive(Context context, Intent intent) {
6596                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6597                if (pkgs != null) {
6598                    for (String pkg : pkgs) {
6599                        synchronized (ActivityManagerService.this) {
6600                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6601                                    0, "query restart")) {
6602                                setResultCode(Activity.RESULT_OK);
6603                                return;
6604                            }
6605                        }
6606                    }
6607                }
6608            }
6609        }, pkgFilter);
6610
6611        IntentFilter dumpheapFilter = new IntentFilter();
6612        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6613        mContext.registerReceiver(new BroadcastReceiver() {
6614            @Override
6615            public void onReceive(Context context, Intent intent) {
6616                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6617                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6618                } else {
6619                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6620                }
6621            }
6622        }, dumpheapFilter);
6623
6624        // Let system services know.
6625        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6626
6627        synchronized (this) {
6628            // Ensure that any processes we had put on hold are now started
6629            // up.
6630            final int NP = mProcessesOnHold.size();
6631            if (NP > 0) {
6632                ArrayList<ProcessRecord> procs =
6633                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6634                for (int ip=0; ip<NP; ip++) {
6635                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6636                            + procs.get(ip));
6637                    startProcessLocked(procs.get(ip), "on-hold", null);
6638                }
6639            }
6640
6641            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6642                // Start looking for apps that are abusing wake locks.
6643                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6644                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6645                // Tell anyone interested that we are done booting!
6646                SystemProperties.set("sys.boot_completed", "1");
6647
6648                // And trigger dev.bootcomplete if we are not showing encryption progress
6649                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6650                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6651                    SystemProperties.set("dev.bootcomplete", "1");
6652                }
6653                mUserController.sendBootCompletedLocked(
6654                        new IIntentReceiver.Stub() {
6655                            @Override
6656                            public void performReceive(Intent intent, int resultCode,
6657                                    String data, Bundle extras, boolean ordered,
6658                                    boolean sticky, int sendingUser) {
6659                                synchronized (ActivityManagerService.this) {
6660                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6661                                            true, false);
6662                                }
6663                            }
6664                        });
6665                scheduleStartProfilesLocked();
6666            }
6667        }
6668    }
6669
6670    @Override
6671    public void bootAnimationComplete() {
6672        final boolean callFinishBooting;
6673        synchronized (this) {
6674            callFinishBooting = mCallFinishBooting;
6675            mBootAnimationComplete = true;
6676        }
6677        if (callFinishBooting) {
6678            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6679            finishBooting();
6680            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6681        }
6682    }
6683
6684    final void ensureBootCompleted() {
6685        boolean booting;
6686        boolean enableScreen;
6687        synchronized (this) {
6688            booting = mBooting;
6689            mBooting = false;
6690            enableScreen = !mBooted;
6691            mBooted = true;
6692        }
6693
6694        if (booting) {
6695            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6696            finishBooting();
6697            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6698        }
6699
6700        if (enableScreen) {
6701            enableScreenAfterBoot();
6702        }
6703    }
6704
6705    @Override
6706    public final void activityResumed(IBinder token) {
6707        final long origId = Binder.clearCallingIdentity();
6708        synchronized(this) {
6709            ActivityStack stack = ActivityRecord.getStackLocked(token);
6710            if (stack != null) {
6711                stack.activityResumedLocked(token);
6712            }
6713        }
6714        Binder.restoreCallingIdentity(origId);
6715    }
6716
6717    @Override
6718    public final void activityPaused(IBinder token) {
6719        final long origId = Binder.clearCallingIdentity();
6720        synchronized(this) {
6721            ActivityStack stack = ActivityRecord.getStackLocked(token);
6722            if (stack != null) {
6723                stack.activityPausedLocked(token, false);
6724            }
6725        }
6726        Binder.restoreCallingIdentity(origId);
6727    }
6728
6729    @Override
6730    public final void activityStopped(IBinder token, Bundle icicle,
6731            PersistableBundle persistentState, CharSequence description) {
6732        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6733
6734        // Refuse possible leaked file descriptors
6735        if (icicle != null && icicle.hasFileDescriptors()) {
6736            throw new IllegalArgumentException("File descriptors passed in Bundle");
6737        }
6738
6739        final long origId = Binder.clearCallingIdentity();
6740
6741        synchronized (this) {
6742            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6743            if (r != null) {
6744                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6745            }
6746        }
6747
6748        trimApplications();
6749
6750        Binder.restoreCallingIdentity(origId);
6751    }
6752
6753    @Override
6754    public final void activityDestroyed(IBinder token) {
6755        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6756        synchronized (this) {
6757            ActivityStack stack = ActivityRecord.getStackLocked(token);
6758            if (stack != null) {
6759                stack.activityDestroyedLocked(token, "activityDestroyed");
6760            }
6761        }
6762    }
6763
6764    @Override
6765    public final void activityRelaunched(IBinder token) {
6766        final long origId = Binder.clearCallingIdentity();
6767        synchronized (this) {
6768            mStackSupervisor.activityRelaunchedLocked(token);
6769        }
6770        Binder.restoreCallingIdentity(origId);
6771    }
6772
6773    @Override
6774    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6775            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6776        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6777                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6778        synchronized (this) {
6779            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6780            if (record == null) {
6781                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6782                        + "found for: " + token);
6783            }
6784            record.setSizeConfigurations(horizontalSizeConfiguration,
6785                    verticalSizeConfigurations, smallestSizeConfigurations);
6786        }
6787    }
6788
6789    @Override
6790    public final void backgroundResourcesReleased(IBinder token) {
6791        final long origId = Binder.clearCallingIdentity();
6792        try {
6793            synchronized (this) {
6794                ActivityStack stack = ActivityRecord.getStackLocked(token);
6795                if (stack != null) {
6796                    stack.backgroundResourcesReleased();
6797                }
6798            }
6799        } finally {
6800            Binder.restoreCallingIdentity(origId);
6801        }
6802    }
6803
6804    @Override
6805    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6806        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6807    }
6808
6809    @Override
6810    public final void notifyEnterAnimationComplete(IBinder token) {
6811        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6812    }
6813
6814    @Override
6815    public String getCallingPackage(IBinder token) {
6816        synchronized (this) {
6817            ActivityRecord r = getCallingRecordLocked(token);
6818            return r != null ? r.info.packageName : null;
6819        }
6820    }
6821
6822    @Override
6823    public ComponentName getCallingActivity(IBinder token) {
6824        synchronized (this) {
6825            ActivityRecord r = getCallingRecordLocked(token);
6826            return r != null ? r.intent.getComponent() : null;
6827        }
6828    }
6829
6830    private ActivityRecord getCallingRecordLocked(IBinder token) {
6831        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6832        if (r == null) {
6833            return null;
6834        }
6835        return r.resultTo;
6836    }
6837
6838    @Override
6839    public ComponentName getActivityClassForToken(IBinder token) {
6840        synchronized(this) {
6841            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6842            if (r == null) {
6843                return null;
6844            }
6845            return r.intent.getComponent();
6846        }
6847    }
6848
6849    @Override
6850    public String getPackageForToken(IBinder token) {
6851        synchronized(this) {
6852            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6853            if (r == null) {
6854                return null;
6855            }
6856            return r.packageName;
6857        }
6858    }
6859
6860    @Override
6861    public boolean isRootVoiceInteraction(IBinder token) {
6862        synchronized(this) {
6863            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6864            if (r == null) {
6865                return false;
6866            }
6867            return r.rootVoiceInteraction;
6868        }
6869    }
6870
6871    @Override
6872    public IIntentSender getIntentSender(int type,
6873            String packageName, IBinder token, String resultWho,
6874            int requestCode, Intent[] intents, String[] resolvedTypes,
6875            int flags, Bundle bOptions, int userId) {
6876        enforceNotIsolatedCaller("getIntentSender");
6877        // Refuse possible leaked file descriptors
6878        if (intents != null) {
6879            if (intents.length < 1) {
6880                throw new IllegalArgumentException("Intents array length must be >= 1");
6881            }
6882            for (int i=0; i<intents.length; i++) {
6883                Intent intent = intents[i];
6884                if (intent != null) {
6885                    if (intent.hasFileDescriptors()) {
6886                        throw new IllegalArgumentException("File descriptors passed in Intent");
6887                    }
6888                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6889                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6890                        throw new IllegalArgumentException(
6891                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6892                    }
6893                    intents[i] = new Intent(intent);
6894                }
6895            }
6896            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6897                throw new IllegalArgumentException(
6898                        "Intent array length does not match resolvedTypes length");
6899            }
6900        }
6901        if (bOptions != null) {
6902            if (bOptions.hasFileDescriptors()) {
6903                throw new IllegalArgumentException("File descriptors passed in options");
6904            }
6905        }
6906
6907        synchronized(this) {
6908            int callingUid = Binder.getCallingUid();
6909            int origUserId = userId;
6910            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6911                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6912                    ALLOW_NON_FULL, "getIntentSender", null);
6913            if (origUserId == UserHandle.USER_CURRENT) {
6914                // We don't want to evaluate this until the pending intent is
6915                // actually executed.  However, we do want to always do the
6916                // security checking for it above.
6917                userId = UserHandle.USER_CURRENT;
6918            }
6919            try {
6920                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6921                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6922                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6923                    if (!UserHandle.isSameApp(callingUid, uid)) {
6924                        String msg = "Permission Denial: getIntentSender() from pid="
6925                            + Binder.getCallingPid()
6926                            + ", uid=" + Binder.getCallingUid()
6927                            + ", (need uid=" + uid + ")"
6928                            + " is not allowed to send as package " + packageName;
6929                        Slog.w(TAG, msg);
6930                        throw new SecurityException(msg);
6931                    }
6932                }
6933
6934                return getIntentSenderLocked(type, packageName, callingUid, userId,
6935                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6936
6937            } catch (RemoteException e) {
6938                throw new SecurityException(e);
6939            }
6940        }
6941    }
6942
6943    IIntentSender getIntentSenderLocked(int type, String packageName,
6944            int callingUid, int userId, IBinder token, String resultWho,
6945            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6946            Bundle bOptions) {
6947        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6948        ActivityRecord activity = null;
6949        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6950            activity = ActivityRecord.isInStackLocked(token);
6951            if (activity == null) {
6952                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6953                return null;
6954            }
6955            if (activity.finishing) {
6956                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6957                return null;
6958            }
6959        }
6960
6961        // We're going to be splicing together extras before sending, so we're
6962        // okay poking into any contained extras.
6963        if (intents != null) {
6964            for (int i = 0; i < intents.length; i++) {
6965                intents[i].setDefusable(true);
6966            }
6967        }
6968        Bundle.setDefusable(bOptions, true);
6969
6970        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6971        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6972        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6973        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6974                |PendingIntent.FLAG_UPDATE_CURRENT);
6975
6976        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6977                type, packageName, activity, resultWho,
6978                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6979        WeakReference<PendingIntentRecord> ref;
6980        ref = mIntentSenderRecords.get(key);
6981        PendingIntentRecord rec = ref != null ? ref.get() : null;
6982        if (rec != null) {
6983            if (!cancelCurrent) {
6984                if (updateCurrent) {
6985                    if (rec.key.requestIntent != null) {
6986                        rec.key.requestIntent.replaceExtras(intents != null ?
6987                                intents[intents.length - 1] : null);
6988                    }
6989                    if (intents != null) {
6990                        intents[intents.length-1] = rec.key.requestIntent;
6991                        rec.key.allIntents = intents;
6992                        rec.key.allResolvedTypes = resolvedTypes;
6993                    } else {
6994                        rec.key.allIntents = null;
6995                        rec.key.allResolvedTypes = null;
6996                    }
6997                }
6998                return rec;
6999            }
7000            rec.canceled = true;
7001            mIntentSenderRecords.remove(key);
7002        }
7003        if (noCreate) {
7004            return rec;
7005        }
7006        rec = new PendingIntentRecord(this, key, callingUid);
7007        mIntentSenderRecords.put(key, rec.ref);
7008        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7009            if (activity.pendingResults == null) {
7010                activity.pendingResults
7011                        = new HashSet<WeakReference<PendingIntentRecord>>();
7012            }
7013            activity.pendingResults.add(rec.ref);
7014        }
7015        return rec;
7016    }
7017
7018    @Override
7019    public void cancelIntentSender(IIntentSender sender) {
7020        if (!(sender instanceof PendingIntentRecord)) {
7021            return;
7022        }
7023        synchronized(this) {
7024            PendingIntentRecord rec = (PendingIntentRecord)sender;
7025            try {
7026                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7027                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7028                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7029                    String msg = "Permission Denial: cancelIntentSender() from pid="
7030                        + Binder.getCallingPid()
7031                        + ", uid=" + Binder.getCallingUid()
7032                        + " is not allowed to cancel packges "
7033                        + rec.key.packageName;
7034                    Slog.w(TAG, msg);
7035                    throw new SecurityException(msg);
7036                }
7037            } catch (RemoteException e) {
7038                throw new SecurityException(e);
7039            }
7040            cancelIntentSenderLocked(rec, true);
7041        }
7042    }
7043
7044    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7045        rec.canceled = true;
7046        mIntentSenderRecords.remove(rec.key);
7047        if (cleanActivity && rec.key.activity != null) {
7048            rec.key.activity.pendingResults.remove(rec.ref);
7049        }
7050    }
7051
7052    @Override
7053    public String getPackageForIntentSender(IIntentSender pendingResult) {
7054        if (!(pendingResult instanceof PendingIntentRecord)) {
7055            return null;
7056        }
7057        try {
7058            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7059            return res.key.packageName;
7060        } catch (ClassCastException e) {
7061        }
7062        return null;
7063    }
7064
7065    @Override
7066    public int getUidForIntentSender(IIntentSender sender) {
7067        if (sender instanceof PendingIntentRecord) {
7068            try {
7069                PendingIntentRecord res = (PendingIntentRecord)sender;
7070                return res.uid;
7071            } catch (ClassCastException e) {
7072            }
7073        }
7074        return -1;
7075    }
7076
7077    @Override
7078    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7079        if (!(pendingResult instanceof PendingIntentRecord)) {
7080            return false;
7081        }
7082        try {
7083            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7084            if (res.key.allIntents == null) {
7085                return false;
7086            }
7087            for (int i=0; i<res.key.allIntents.length; i++) {
7088                Intent intent = res.key.allIntents[i];
7089                if (intent.getPackage() != null && intent.getComponent() != null) {
7090                    return false;
7091                }
7092            }
7093            return true;
7094        } catch (ClassCastException e) {
7095        }
7096        return false;
7097    }
7098
7099    @Override
7100    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7101        if (!(pendingResult instanceof PendingIntentRecord)) {
7102            return false;
7103        }
7104        try {
7105            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7106            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7107                return true;
7108            }
7109            return false;
7110        } catch (ClassCastException e) {
7111        }
7112        return false;
7113    }
7114
7115    @Override
7116    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7117        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7118                "getIntentForIntentSender()");
7119        if (!(pendingResult instanceof PendingIntentRecord)) {
7120            return null;
7121        }
7122        try {
7123            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7124            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7125        } catch (ClassCastException e) {
7126        }
7127        return null;
7128    }
7129
7130    @Override
7131    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7132        if (!(pendingResult instanceof PendingIntentRecord)) {
7133            return null;
7134        }
7135        try {
7136            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7137            synchronized (this) {
7138                return getTagForIntentSenderLocked(res, prefix);
7139            }
7140        } catch (ClassCastException e) {
7141        }
7142        return null;
7143    }
7144
7145    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7146        final Intent intent = res.key.requestIntent;
7147        if (intent != null) {
7148            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7149                    || res.lastTagPrefix.equals(prefix))) {
7150                return res.lastTag;
7151            }
7152            res.lastTagPrefix = prefix;
7153            final StringBuilder sb = new StringBuilder(128);
7154            if (prefix != null) {
7155                sb.append(prefix);
7156            }
7157            if (intent.getAction() != null) {
7158                sb.append(intent.getAction());
7159            } else if (intent.getComponent() != null) {
7160                intent.getComponent().appendShortString(sb);
7161            } else {
7162                sb.append("?");
7163            }
7164            return res.lastTag = sb.toString();
7165        }
7166        return null;
7167    }
7168
7169    @Override
7170    public void setProcessLimit(int max) {
7171        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7172                "setProcessLimit()");
7173        synchronized (this) {
7174            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7175            mProcessLimitOverride = max;
7176        }
7177        trimApplications();
7178    }
7179
7180    @Override
7181    public int getProcessLimit() {
7182        synchronized (this) {
7183            return mProcessLimitOverride;
7184        }
7185    }
7186
7187    void foregroundTokenDied(ForegroundToken token) {
7188        synchronized (ActivityManagerService.this) {
7189            synchronized (mPidsSelfLocked) {
7190                ForegroundToken cur
7191                    = mForegroundProcesses.get(token.pid);
7192                if (cur != token) {
7193                    return;
7194                }
7195                mForegroundProcesses.remove(token.pid);
7196                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7197                if (pr == null) {
7198                    return;
7199                }
7200                pr.forcingToForeground = null;
7201                updateProcessForegroundLocked(pr, false, false);
7202            }
7203            updateOomAdjLocked();
7204        }
7205    }
7206
7207    @Override
7208    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7209        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7210                "setProcessForeground()");
7211        synchronized(this) {
7212            boolean changed = false;
7213
7214            synchronized (mPidsSelfLocked) {
7215                ProcessRecord pr = mPidsSelfLocked.get(pid);
7216                if (pr == null && isForeground) {
7217                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7218                    return;
7219                }
7220                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7221                if (oldToken != null) {
7222                    oldToken.token.unlinkToDeath(oldToken, 0);
7223                    mForegroundProcesses.remove(pid);
7224                    if (pr != null) {
7225                        pr.forcingToForeground = null;
7226                    }
7227                    changed = true;
7228                }
7229                if (isForeground && token != null) {
7230                    ForegroundToken newToken = new ForegroundToken() {
7231                        @Override
7232                        public void binderDied() {
7233                            foregroundTokenDied(this);
7234                        }
7235                    };
7236                    newToken.pid = pid;
7237                    newToken.token = token;
7238                    try {
7239                        token.linkToDeath(newToken, 0);
7240                        mForegroundProcesses.put(pid, newToken);
7241                        pr.forcingToForeground = token;
7242                        changed = true;
7243                    } catch (RemoteException e) {
7244                        // If the process died while doing this, we will later
7245                        // do the cleanup with the process death link.
7246                    }
7247                }
7248            }
7249
7250            if (changed) {
7251                updateOomAdjLocked();
7252            }
7253        }
7254    }
7255
7256    @Override
7257    public boolean isAppForeground(int uid) throws RemoteException {
7258        synchronized (this) {
7259            UidRecord uidRec = mActiveUids.get(uid);
7260            if (uidRec == null || uidRec.idle) {
7261                return false;
7262            }
7263            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7264        }
7265    }
7266
7267    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7268    // be guarded by permission checking.
7269    int getUidState(int uid) {
7270        synchronized (this) {
7271            UidRecord uidRec = mActiveUids.get(uid);
7272            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7273        }
7274    }
7275
7276    @Override
7277    public boolean isInMultiWindowMode(IBinder token) {
7278        final long origId = Binder.clearCallingIdentity();
7279        try {
7280            synchronized(this) {
7281                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7282                if (r == null) {
7283                    return false;
7284                }
7285                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7286                return !r.task.mFullscreen;
7287            }
7288        } finally {
7289            Binder.restoreCallingIdentity(origId);
7290        }
7291    }
7292
7293    @Override
7294    public boolean isInPictureInPictureMode(IBinder token) {
7295        final long origId = Binder.clearCallingIdentity();
7296        try {
7297            synchronized(this) {
7298                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7299                if (stack == null) {
7300                    return false;
7301                }
7302                return stack.mStackId == PINNED_STACK_ID;
7303            }
7304        } finally {
7305            Binder.restoreCallingIdentity(origId);
7306        }
7307    }
7308
7309    @Override
7310    public void enterPictureInPictureMode(IBinder token) {
7311        final long origId = Binder.clearCallingIdentity();
7312        try {
7313            synchronized(this) {
7314                if (!mSupportsPictureInPicture) {
7315                    throw new IllegalStateException("enterPictureInPictureMode: "
7316                            + "Device doesn't support picture-in-picture mode.");
7317                }
7318
7319                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7320
7321                if (r == null) {
7322                    throw new IllegalStateException("enterPictureInPictureMode: "
7323                            + "Can't find activity for token=" + token);
7324                }
7325
7326                if (!r.supportsPictureInPicture()) {
7327                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7328                            + "Picture-In-Picture not supported for r=" + r);
7329                }
7330
7331                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7332                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7333                        ? mDefaultPinnedStackBounds : null;
7334
7335                mStackSupervisor.moveActivityToPinnedStackLocked(
7336                        r, "enterPictureInPictureMode", bounds);
7337            }
7338        } finally {
7339            Binder.restoreCallingIdentity(origId);
7340        }
7341    }
7342
7343    // =========================================================
7344    // PROCESS INFO
7345    // =========================================================
7346
7347    static class ProcessInfoService extends IProcessInfoService.Stub {
7348        final ActivityManagerService mActivityManagerService;
7349        ProcessInfoService(ActivityManagerService activityManagerService) {
7350            mActivityManagerService = activityManagerService;
7351        }
7352
7353        @Override
7354        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7355            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7356                    /*in*/ pids, /*out*/ states, null);
7357        }
7358
7359        @Override
7360        public void getProcessStatesAndOomScoresFromPids(
7361                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7362            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7363                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7364        }
7365    }
7366
7367    /**
7368     * For each PID in the given input array, write the current process state
7369     * for that process into the states array, or -1 to indicate that no
7370     * process with the given PID exists. If scores array is provided, write
7371     * the oom score for the process into the scores array, with INVALID_ADJ
7372     * indicating the PID doesn't exist.
7373     */
7374    public void getProcessStatesAndOomScoresForPIDs(
7375            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7376        if (scores != null) {
7377            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7378                    "getProcessStatesAndOomScoresForPIDs()");
7379        }
7380
7381        if (pids == null) {
7382            throw new NullPointerException("pids");
7383        } else if (states == null) {
7384            throw new NullPointerException("states");
7385        } else if (pids.length != states.length) {
7386            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7387        } else if (scores != null && pids.length != scores.length) {
7388            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7389        }
7390
7391        synchronized (mPidsSelfLocked) {
7392            for (int i = 0; i < pids.length; i++) {
7393                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7394                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7395                        pr.curProcState;
7396                if (scores != null) {
7397                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7398                }
7399            }
7400        }
7401    }
7402
7403    // =========================================================
7404    // PERMISSIONS
7405    // =========================================================
7406
7407    static class PermissionController extends IPermissionController.Stub {
7408        ActivityManagerService mActivityManagerService;
7409        PermissionController(ActivityManagerService activityManagerService) {
7410            mActivityManagerService = activityManagerService;
7411        }
7412
7413        @Override
7414        public boolean checkPermission(String permission, int pid, int uid) {
7415            return mActivityManagerService.checkPermission(permission, pid,
7416                    uid) == PackageManager.PERMISSION_GRANTED;
7417        }
7418
7419        @Override
7420        public String[] getPackagesForUid(int uid) {
7421            return mActivityManagerService.mContext.getPackageManager()
7422                    .getPackagesForUid(uid);
7423        }
7424
7425        @Override
7426        public boolean isRuntimePermission(String permission) {
7427            try {
7428                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7429                        .getPermissionInfo(permission, 0);
7430                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7431            } catch (NameNotFoundException nnfe) {
7432                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7433            }
7434            return false;
7435        }
7436    }
7437
7438    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7439        @Override
7440        public int checkComponentPermission(String permission, int pid, int uid,
7441                int owningUid, boolean exported) {
7442            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7443                    owningUid, exported);
7444        }
7445
7446        @Override
7447        public Object getAMSLock() {
7448            return ActivityManagerService.this;
7449        }
7450    }
7451
7452    /**
7453     * This can be called with or without the global lock held.
7454     */
7455    int checkComponentPermission(String permission, int pid, int uid,
7456            int owningUid, boolean exported) {
7457        if (pid == MY_PID) {
7458            return PackageManager.PERMISSION_GRANTED;
7459        }
7460        return ActivityManager.checkComponentPermission(permission, uid,
7461                owningUid, exported);
7462    }
7463
7464    /**
7465     * As the only public entry point for permissions checking, this method
7466     * can enforce the semantic that requesting a check on a null global
7467     * permission is automatically denied.  (Internally a null permission
7468     * string is used when calling {@link #checkComponentPermission} in cases
7469     * when only uid-based security is needed.)
7470     *
7471     * This can be called with or without the global lock held.
7472     */
7473    @Override
7474    public int checkPermission(String permission, int pid, int uid) {
7475        if (permission == null) {
7476            return PackageManager.PERMISSION_DENIED;
7477        }
7478        return checkComponentPermission(permission, pid, uid, -1, true);
7479    }
7480
7481    @Override
7482    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7483        if (permission == null) {
7484            return PackageManager.PERMISSION_DENIED;
7485        }
7486
7487        // We might be performing an operation on behalf of an indirect binder
7488        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7489        // client identity accordingly before proceeding.
7490        Identity tlsIdentity = sCallerIdentity.get();
7491        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7492            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7493                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7494            uid = tlsIdentity.uid;
7495            pid = tlsIdentity.pid;
7496        }
7497
7498        return checkComponentPermission(permission, pid, uid, -1, true);
7499    }
7500
7501    /**
7502     * Binder IPC calls go through the public entry point.
7503     * This can be called with or without the global lock held.
7504     */
7505    int checkCallingPermission(String permission) {
7506        return checkPermission(permission,
7507                Binder.getCallingPid(),
7508                UserHandle.getAppId(Binder.getCallingUid()));
7509    }
7510
7511    /**
7512     * This can be called with or without the global lock held.
7513     */
7514    void enforceCallingPermission(String permission, String func) {
7515        if (checkCallingPermission(permission)
7516                == PackageManager.PERMISSION_GRANTED) {
7517            return;
7518        }
7519
7520        String msg = "Permission Denial: " + func + " from pid="
7521                + Binder.getCallingPid()
7522                + ", uid=" + Binder.getCallingUid()
7523                + " requires " + permission;
7524        Slog.w(TAG, msg);
7525        throw new SecurityException(msg);
7526    }
7527
7528    /**
7529     * Determine if UID is holding permissions required to access {@link Uri} in
7530     * the given {@link ProviderInfo}. Final permission checking is always done
7531     * in {@link ContentProvider}.
7532     */
7533    private final boolean checkHoldingPermissionsLocked(
7534            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7535        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7536                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7537        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7538            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7539                    != PERMISSION_GRANTED) {
7540                return false;
7541            }
7542        }
7543        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7544    }
7545
7546    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7547            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7548        if (pi.applicationInfo.uid == uid) {
7549            return true;
7550        } else if (!pi.exported) {
7551            return false;
7552        }
7553
7554        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7555        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7556        try {
7557            // check if target holds top-level <provider> permissions
7558            if (!readMet && pi.readPermission != null && considerUidPermissions
7559                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7560                readMet = true;
7561            }
7562            if (!writeMet && pi.writePermission != null && considerUidPermissions
7563                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7564                writeMet = true;
7565            }
7566
7567            // track if unprotected read/write is allowed; any denied
7568            // <path-permission> below removes this ability
7569            boolean allowDefaultRead = pi.readPermission == null;
7570            boolean allowDefaultWrite = pi.writePermission == null;
7571
7572            // check if target holds any <path-permission> that match uri
7573            final PathPermission[] pps = pi.pathPermissions;
7574            if (pps != null) {
7575                final String path = grantUri.uri.getPath();
7576                int i = pps.length;
7577                while (i > 0 && (!readMet || !writeMet)) {
7578                    i--;
7579                    PathPermission pp = pps[i];
7580                    if (pp.match(path)) {
7581                        if (!readMet) {
7582                            final String pprperm = pp.getReadPermission();
7583                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7584                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7585                                    + ": match=" + pp.match(path)
7586                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7587                            if (pprperm != null) {
7588                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7589                                        == PERMISSION_GRANTED) {
7590                                    readMet = true;
7591                                } else {
7592                                    allowDefaultRead = false;
7593                                }
7594                            }
7595                        }
7596                        if (!writeMet) {
7597                            final String ppwperm = pp.getWritePermission();
7598                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7599                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7600                                    + ": match=" + pp.match(path)
7601                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7602                            if (ppwperm != null) {
7603                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7604                                        == PERMISSION_GRANTED) {
7605                                    writeMet = true;
7606                                } else {
7607                                    allowDefaultWrite = false;
7608                                }
7609                            }
7610                        }
7611                    }
7612                }
7613            }
7614
7615            // grant unprotected <provider> read/write, if not blocked by
7616            // <path-permission> above
7617            if (allowDefaultRead) readMet = true;
7618            if (allowDefaultWrite) writeMet = true;
7619
7620        } catch (RemoteException e) {
7621            return false;
7622        }
7623
7624        return readMet && writeMet;
7625    }
7626
7627    public int getAppStartMode(int uid, String packageName) {
7628        synchronized (this) {
7629            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7630        }
7631    }
7632
7633    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7634            boolean allowWhenForeground) {
7635        UidRecord uidRec = mActiveUids.get(uid);
7636        if (!mLenientBackgroundCheck) {
7637            if (!allowWhenForeground || uidRec == null
7638                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7639                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7640                        packageName) != AppOpsManager.MODE_ALLOWED) {
7641                    return ActivityManager.APP_START_MODE_DELAYED;
7642                }
7643            }
7644
7645        } else if (uidRec == null || uidRec.idle) {
7646            if (callingPid >= 0) {
7647                ProcessRecord proc;
7648                synchronized (mPidsSelfLocked) {
7649                    proc = mPidsSelfLocked.get(callingPid);
7650                }
7651                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7652                    // Whoever is instigating this is in the foreground, so we will allow it
7653                    // to go through.
7654                    return ActivityManager.APP_START_MODE_NORMAL;
7655                }
7656            }
7657            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7658                    != AppOpsManager.MODE_ALLOWED) {
7659                return ActivityManager.APP_START_MODE_DELAYED;
7660            }
7661        }
7662        return ActivityManager.APP_START_MODE_NORMAL;
7663    }
7664
7665    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7666        ProviderInfo pi = null;
7667        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7668        if (cpr != null) {
7669            pi = cpr.info;
7670        } else {
7671            try {
7672                pi = AppGlobals.getPackageManager().resolveContentProvider(
7673                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7674            } catch (RemoteException ex) {
7675            }
7676        }
7677        return pi;
7678    }
7679
7680    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7681        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7682        if (targetUris != null) {
7683            return targetUris.get(grantUri);
7684        }
7685        return null;
7686    }
7687
7688    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7689            String targetPkg, int targetUid, GrantUri grantUri) {
7690        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7691        if (targetUris == null) {
7692            targetUris = Maps.newArrayMap();
7693            mGrantedUriPermissions.put(targetUid, targetUris);
7694        }
7695
7696        UriPermission perm = targetUris.get(grantUri);
7697        if (perm == null) {
7698            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7699            targetUris.put(grantUri, perm);
7700        }
7701
7702        return perm;
7703    }
7704
7705    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7706            final int modeFlags) {
7707        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7708        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7709                : UriPermission.STRENGTH_OWNED;
7710
7711        // Root gets to do everything.
7712        if (uid == 0) {
7713            return true;
7714        }
7715
7716        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7717        if (perms == null) return false;
7718
7719        // First look for exact match
7720        final UriPermission exactPerm = perms.get(grantUri);
7721        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7722            return true;
7723        }
7724
7725        // No exact match, look for prefixes
7726        final int N = perms.size();
7727        for (int i = 0; i < N; i++) {
7728            final UriPermission perm = perms.valueAt(i);
7729            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7730                    && perm.getStrength(modeFlags) >= minStrength) {
7731                return true;
7732            }
7733        }
7734
7735        return false;
7736    }
7737
7738    /**
7739     * @param uri This uri must NOT contain an embedded userId.
7740     * @param userId The userId in which the uri is to be resolved.
7741     */
7742    @Override
7743    public int checkUriPermission(Uri uri, int pid, int uid,
7744            final int modeFlags, int userId, IBinder callerToken) {
7745        enforceNotIsolatedCaller("checkUriPermission");
7746
7747        // Another redirected-binder-call permissions check as in
7748        // {@link checkPermissionWithToken}.
7749        Identity tlsIdentity = sCallerIdentity.get();
7750        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7751            uid = tlsIdentity.uid;
7752            pid = tlsIdentity.pid;
7753        }
7754
7755        // Our own process gets to do everything.
7756        if (pid == MY_PID) {
7757            return PackageManager.PERMISSION_GRANTED;
7758        }
7759        synchronized (this) {
7760            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7761                    ? PackageManager.PERMISSION_GRANTED
7762                    : PackageManager.PERMISSION_DENIED;
7763        }
7764    }
7765
7766    /**
7767     * Check if the targetPkg can be granted permission to access uri by
7768     * the callingUid using the given modeFlags.  Throws a security exception
7769     * if callingUid is not allowed to do this.  Returns the uid of the target
7770     * if the URI permission grant should be performed; returns -1 if it is not
7771     * needed (for example targetPkg already has permission to access the URI).
7772     * If you already know the uid of the target, you can supply it in
7773     * lastTargetUid else set that to -1.
7774     */
7775    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7776            final int modeFlags, int lastTargetUid) {
7777        if (!Intent.isAccessUriMode(modeFlags)) {
7778            return -1;
7779        }
7780
7781        if (targetPkg != null) {
7782            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7783                    "Checking grant " + targetPkg + " permission to " + grantUri);
7784        }
7785
7786        final IPackageManager pm = AppGlobals.getPackageManager();
7787
7788        // If this is not a content: uri, we can't do anything with it.
7789        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7790            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7791                    "Can't grant URI permission for non-content URI: " + grantUri);
7792            return -1;
7793        }
7794
7795        final String authority = grantUri.uri.getAuthority();
7796        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7797        if (pi == null) {
7798            Slog.w(TAG, "No content provider found for permission check: " +
7799                    grantUri.uri.toSafeString());
7800            return -1;
7801        }
7802
7803        int targetUid = lastTargetUid;
7804        if (targetUid < 0 && targetPkg != null) {
7805            try {
7806                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7807                        UserHandle.getUserId(callingUid));
7808                if (targetUid < 0) {
7809                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7810                            "Can't grant URI permission no uid for: " + targetPkg);
7811                    return -1;
7812                }
7813            } catch (RemoteException ex) {
7814                return -1;
7815            }
7816        }
7817
7818        if (targetUid >= 0) {
7819            // First...  does the target actually need this permission?
7820            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7821                // No need to grant the target this permission.
7822                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7823                        "Target " + targetPkg + " already has full permission to " + grantUri);
7824                return -1;
7825            }
7826        } else {
7827            // First...  there is no target package, so can anyone access it?
7828            boolean allowed = pi.exported;
7829            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7830                if (pi.readPermission != null) {
7831                    allowed = false;
7832                }
7833            }
7834            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7835                if (pi.writePermission != null) {
7836                    allowed = false;
7837                }
7838            }
7839            if (allowed) {
7840                return -1;
7841            }
7842        }
7843
7844        /* There is a special cross user grant if:
7845         * - The target is on another user.
7846         * - Apps on the current user can access the uri without any uid permissions.
7847         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7848         * grant uri permissions.
7849         */
7850        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7851                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7852                modeFlags, false /*without considering the uid permissions*/);
7853
7854        // Second...  is the provider allowing granting of URI permissions?
7855        if (!specialCrossUserGrant) {
7856            if (!pi.grantUriPermissions) {
7857                throw new SecurityException("Provider " + pi.packageName
7858                        + "/" + pi.name
7859                        + " does not allow granting of Uri permissions (uri "
7860                        + grantUri + ")");
7861            }
7862            if (pi.uriPermissionPatterns != null) {
7863                final int N = pi.uriPermissionPatterns.length;
7864                boolean allowed = false;
7865                for (int i=0; i<N; i++) {
7866                    if (pi.uriPermissionPatterns[i] != null
7867                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7868                        allowed = true;
7869                        break;
7870                    }
7871                }
7872                if (!allowed) {
7873                    throw new SecurityException("Provider " + pi.packageName
7874                            + "/" + pi.name
7875                            + " does not allow granting of permission to path of Uri "
7876                            + grantUri);
7877                }
7878            }
7879        }
7880
7881        // Third...  does the caller itself have permission to access
7882        // this uri?
7883        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7884            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7885                // Require they hold a strong enough Uri permission
7886                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7887                    throw new SecurityException("Uid " + callingUid
7888                            + " does not have permission to uri " + grantUri);
7889                }
7890            }
7891        }
7892        return targetUid;
7893    }
7894
7895    /**
7896     * @param uri This uri must NOT contain an embedded userId.
7897     * @param userId The userId in which the uri is to be resolved.
7898     */
7899    @Override
7900    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7901            final int modeFlags, int userId) {
7902        enforceNotIsolatedCaller("checkGrantUriPermission");
7903        synchronized(this) {
7904            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7905                    new GrantUri(userId, uri, false), modeFlags, -1);
7906        }
7907    }
7908
7909    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7910            final int modeFlags, UriPermissionOwner owner) {
7911        if (!Intent.isAccessUriMode(modeFlags)) {
7912            return;
7913        }
7914
7915        // So here we are: the caller has the assumed permission
7916        // to the uri, and the target doesn't.  Let's now give this to
7917        // the target.
7918
7919        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7920                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7921
7922        final String authority = grantUri.uri.getAuthority();
7923        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7924        if (pi == null) {
7925            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7926            return;
7927        }
7928
7929        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7930            grantUri.prefix = true;
7931        }
7932        final UriPermission perm = findOrCreateUriPermissionLocked(
7933                pi.packageName, targetPkg, targetUid, grantUri);
7934        perm.grantModes(modeFlags, owner);
7935    }
7936
7937    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7938            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7939        if (targetPkg == null) {
7940            throw new NullPointerException("targetPkg");
7941        }
7942        int targetUid;
7943        final IPackageManager pm = AppGlobals.getPackageManager();
7944        try {
7945            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7946        } catch (RemoteException ex) {
7947            return;
7948        }
7949
7950        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7951                targetUid);
7952        if (targetUid < 0) {
7953            return;
7954        }
7955
7956        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7957                owner);
7958    }
7959
7960    static class NeededUriGrants extends ArrayList<GrantUri> {
7961        final String targetPkg;
7962        final int targetUid;
7963        final int flags;
7964
7965        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7966            this.targetPkg = targetPkg;
7967            this.targetUid = targetUid;
7968            this.flags = flags;
7969        }
7970    }
7971
7972    /**
7973     * Like checkGrantUriPermissionLocked, but takes an Intent.
7974     */
7975    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7976            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7977        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7978                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7979                + " clip=" + (intent != null ? intent.getClipData() : null)
7980                + " from " + intent + "; flags=0x"
7981                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7982
7983        if (targetPkg == null) {
7984            throw new NullPointerException("targetPkg");
7985        }
7986
7987        if (intent == null) {
7988            return null;
7989        }
7990        Uri data = intent.getData();
7991        ClipData clip = intent.getClipData();
7992        if (data == null && clip == null) {
7993            return null;
7994        }
7995        // Default userId for uris in the intent (if they don't specify it themselves)
7996        int contentUserHint = intent.getContentUserHint();
7997        if (contentUserHint == UserHandle.USER_CURRENT) {
7998            contentUserHint = UserHandle.getUserId(callingUid);
7999        }
8000        final IPackageManager pm = AppGlobals.getPackageManager();
8001        int targetUid;
8002        if (needed != null) {
8003            targetUid = needed.targetUid;
8004        } else {
8005            try {
8006                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8007                        targetUserId);
8008            } catch (RemoteException ex) {
8009                return null;
8010            }
8011            if (targetUid < 0) {
8012                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8013                        "Can't grant URI permission no uid for: " + targetPkg
8014                        + " on user " + targetUserId);
8015                return null;
8016            }
8017        }
8018        if (data != null) {
8019            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8020            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8021                    targetUid);
8022            if (targetUid > 0) {
8023                if (needed == null) {
8024                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8025                }
8026                needed.add(grantUri);
8027            }
8028        }
8029        if (clip != null) {
8030            for (int i=0; i<clip.getItemCount(); i++) {
8031                Uri uri = clip.getItemAt(i).getUri();
8032                if (uri != null) {
8033                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8034                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8035                            targetUid);
8036                    if (targetUid > 0) {
8037                        if (needed == null) {
8038                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8039                        }
8040                        needed.add(grantUri);
8041                    }
8042                } else {
8043                    Intent clipIntent = clip.getItemAt(i).getIntent();
8044                    if (clipIntent != null) {
8045                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8046                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8047                        if (newNeeded != null) {
8048                            needed = newNeeded;
8049                        }
8050                    }
8051                }
8052            }
8053        }
8054
8055        return needed;
8056    }
8057
8058    /**
8059     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8060     */
8061    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8062            UriPermissionOwner owner) {
8063        if (needed != null) {
8064            for (int i=0; i<needed.size(); i++) {
8065                GrantUri grantUri = needed.get(i);
8066                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8067                        grantUri, needed.flags, owner);
8068            }
8069        }
8070    }
8071
8072    void grantUriPermissionFromIntentLocked(int callingUid,
8073            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8074        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8075                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8076        if (needed == null) {
8077            return;
8078        }
8079
8080        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8081    }
8082
8083    /**
8084     * @param uri This uri must NOT contain an embedded userId.
8085     * @param userId The userId in which the uri is to be resolved.
8086     */
8087    @Override
8088    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8089            final int modeFlags, int userId) {
8090        enforceNotIsolatedCaller("grantUriPermission");
8091        GrantUri grantUri = new GrantUri(userId, uri, false);
8092        synchronized(this) {
8093            final ProcessRecord r = getRecordForAppLocked(caller);
8094            if (r == null) {
8095                throw new SecurityException("Unable to find app for caller "
8096                        + caller
8097                        + " when granting permission to uri " + grantUri);
8098            }
8099            if (targetPkg == null) {
8100                throw new IllegalArgumentException("null target");
8101            }
8102            if (grantUri == null) {
8103                throw new IllegalArgumentException("null uri");
8104            }
8105
8106            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8107                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8108                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8109                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8110
8111            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8112                    UserHandle.getUserId(r.uid));
8113        }
8114    }
8115
8116    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8117        if (perm.modeFlags == 0) {
8118            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8119                    perm.targetUid);
8120            if (perms != null) {
8121                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8122                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8123
8124                perms.remove(perm.uri);
8125                if (perms.isEmpty()) {
8126                    mGrantedUriPermissions.remove(perm.targetUid);
8127                }
8128            }
8129        }
8130    }
8131
8132    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8133        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134                "Revoking all granted permissions to " + grantUri);
8135
8136        final IPackageManager pm = AppGlobals.getPackageManager();
8137        final String authority = grantUri.uri.getAuthority();
8138        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8139        if (pi == null) {
8140            Slog.w(TAG, "No content provider found for permission revoke: "
8141                    + grantUri.toSafeString());
8142            return;
8143        }
8144
8145        // Does the caller have this permission on the URI?
8146        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8147            // If they don't have direct access to the URI, then revoke any
8148            // ownerless URI permissions that have been granted to them.
8149            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8150            if (perms != null) {
8151                boolean persistChanged = false;
8152                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8153                    final UriPermission perm = it.next();
8154                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8155                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8156                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8157                                "Revoking non-owned " + perm.targetUid
8158                                + " permission to " + perm.uri);
8159                        persistChanged |= perm.revokeModes(
8160                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8161                        if (perm.modeFlags == 0) {
8162                            it.remove();
8163                        }
8164                    }
8165                }
8166                if (perms.isEmpty()) {
8167                    mGrantedUriPermissions.remove(callingUid);
8168                }
8169                if (persistChanged) {
8170                    schedulePersistUriGrants();
8171                }
8172            }
8173            return;
8174        }
8175
8176        boolean persistChanged = false;
8177
8178        // Go through all of the permissions and remove any that match.
8179        int N = mGrantedUriPermissions.size();
8180        for (int i = 0; i < N; i++) {
8181            final int targetUid = mGrantedUriPermissions.keyAt(i);
8182            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8183
8184            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8185                final UriPermission perm = it.next();
8186                if (perm.uri.sourceUserId == grantUri.sourceUserId
8187                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8188                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8189                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8190                    persistChanged |= perm.revokeModes(
8191                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8192                    if (perm.modeFlags == 0) {
8193                        it.remove();
8194                    }
8195                }
8196            }
8197
8198            if (perms.isEmpty()) {
8199                mGrantedUriPermissions.remove(targetUid);
8200                N--;
8201                i--;
8202            }
8203        }
8204
8205        if (persistChanged) {
8206            schedulePersistUriGrants();
8207        }
8208    }
8209
8210    /**
8211     * @param uri This uri must NOT contain an embedded userId.
8212     * @param userId The userId in which the uri is to be resolved.
8213     */
8214    @Override
8215    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8216            int userId) {
8217        enforceNotIsolatedCaller("revokeUriPermission");
8218        synchronized(this) {
8219            final ProcessRecord r = getRecordForAppLocked(caller);
8220            if (r == null) {
8221                throw new SecurityException("Unable to find app for caller "
8222                        + caller
8223                        + " when revoking permission to uri " + uri);
8224            }
8225            if (uri == null) {
8226                Slog.w(TAG, "revokeUriPermission: null uri");
8227                return;
8228            }
8229
8230            if (!Intent.isAccessUriMode(modeFlags)) {
8231                return;
8232            }
8233
8234            final String authority = uri.getAuthority();
8235            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8236            if (pi == null) {
8237                Slog.w(TAG, "No content provider found for permission revoke: "
8238                        + uri.toSafeString());
8239                return;
8240            }
8241
8242            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8243        }
8244    }
8245
8246    /**
8247     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8248     * given package.
8249     *
8250     * @param packageName Package name to match, or {@code null} to apply to all
8251     *            packages.
8252     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8253     *            to all users.
8254     * @param persistable If persistable grants should be removed.
8255     */
8256    private void removeUriPermissionsForPackageLocked(
8257            String packageName, int userHandle, boolean persistable) {
8258        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8259            throw new IllegalArgumentException("Must narrow by either package or user");
8260        }
8261
8262        boolean persistChanged = false;
8263
8264        int N = mGrantedUriPermissions.size();
8265        for (int i = 0; i < N; i++) {
8266            final int targetUid = mGrantedUriPermissions.keyAt(i);
8267            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8268
8269            // Only inspect grants matching user
8270            if (userHandle == UserHandle.USER_ALL
8271                    || userHandle == UserHandle.getUserId(targetUid)) {
8272                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8273                    final UriPermission perm = it.next();
8274
8275                    // Only inspect grants matching package
8276                    if (packageName == null || perm.sourcePkg.equals(packageName)
8277                            || perm.targetPkg.equals(packageName)) {
8278                        persistChanged |= perm.revokeModes(persistable
8279                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8280
8281                        // Only remove when no modes remain; any persisted grants
8282                        // will keep this alive.
8283                        if (perm.modeFlags == 0) {
8284                            it.remove();
8285                        }
8286                    }
8287                }
8288
8289                if (perms.isEmpty()) {
8290                    mGrantedUriPermissions.remove(targetUid);
8291                    N--;
8292                    i--;
8293                }
8294            }
8295        }
8296
8297        if (persistChanged) {
8298            schedulePersistUriGrants();
8299        }
8300    }
8301
8302    @Override
8303    public IBinder newUriPermissionOwner(String name) {
8304        enforceNotIsolatedCaller("newUriPermissionOwner");
8305        synchronized(this) {
8306            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8307            return owner.getExternalTokenLocked();
8308        }
8309    }
8310
8311    @Override
8312    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8313        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8314        synchronized(this) {
8315            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8316            if (r == null) {
8317                throw new IllegalArgumentException("Activity does not exist; token="
8318                        + activityToken);
8319            }
8320            return r.getUriPermissionsLocked().getExternalTokenLocked();
8321        }
8322    }
8323    /**
8324     * @param uri This uri must NOT contain an embedded userId.
8325     * @param sourceUserId The userId in which the uri is to be resolved.
8326     * @param targetUserId The userId of the app that receives the grant.
8327     */
8328    @Override
8329    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8330            final int modeFlags, int sourceUserId, int targetUserId) {
8331        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8332                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8333                "grantUriPermissionFromOwner", null);
8334        synchronized(this) {
8335            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8336            if (owner == null) {
8337                throw new IllegalArgumentException("Unknown owner: " + token);
8338            }
8339            if (fromUid != Binder.getCallingUid()) {
8340                if (Binder.getCallingUid() != Process.myUid()) {
8341                    // Only system code can grant URI permissions on behalf
8342                    // of other users.
8343                    throw new SecurityException("nice try");
8344                }
8345            }
8346            if (targetPkg == null) {
8347                throw new IllegalArgumentException("null target");
8348            }
8349            if (uri == null) {
8350                throw new IllegalArgumentException("null uri");
8351            }
8352
8353            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8354                    modeFlags, owner, targetUserId);
8355        }
8356    }
8357
8358    /**
8359     * @param uri This uri must NOT contain an embedded userId.
8360     * @param userId The userId in which the uri is to be resolved.
8361     */
8362    @Override
8363    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8364        synchronized(this) {
8365            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8366            if (owner == null) {
8367                throw new IllegalArgumentException("Unknown owner: " + token);
8368            }
8369
8370            if (uri == null) {
8371                owner.removeUriPermissionsLocked(mode);
8372            } else {
8373                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8374            }
8375        }
8376    }
8377
8378    private void schedulePersistUriGrants() {
8379        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8380            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8381                    10 * DateUtils.SECOND_IN_MILLIS);
8382        }
8383    }
8384
8385    private void writeGrantedUriPermissions() {
8386        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8387
8388        // Snapshot permissions so we can persist without lock
8389        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8390        synchronized (this) {
8391            final int size = mGrantedUriPermissions.size();
8392            for (int i = 0; i < size; i++) {
8393                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8394                for (UriPermission perm : perms.values()) {
8395                    if (perm.persistedModeFlags != 0) {
8396                        persist.add(perm.snapshot());
8397                    }
8398                }
8399            }
8400        }
8401
8402        FileOutputStream fos = null;
8403        try {
8404            fos = mGrantFile.startWrite();
8405
8406            XmlSerializer out = new FastXmlSerializer();
8407            out.setOutput(fos, StandardCharsets.UTF_8.name());
8408            out.startDocument(null, true);
8409            out.startTag(null, TAG_URI_GRANTS);
8410            for (UriPermission.Snapshot perm : persist) {
8411                out.startTag(null, TAG_URI_GRANT);
8412                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8413                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8414                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8415                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8416                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8417                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8418                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8419                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8420                out.endTag(null, TAG_URI_GRANT);
8421            }
8422            out.endTag(null, TAG_URI_GRANTS);
8423            out.endDocument();
8424
8425            mGrantFile.finishWrite(fos);
8426        } catch (IOException e) {
8427            if (fos != null) {
8428                mGrantFile.failWrite(fos);
8429            }
8430        }
8431    }
8432
8433    private void readGrantedUriPermissionsLocked() {
8434        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8435
8436        final long now = System.currentTimeMillis();
8437
8438        FileInputStream fis = null;
8439        try {
8440            fis = mGrantFile.openRead();
8441            final XmlPullParser in = Xml.newPullParser();
8442            in.setInput(fis, StandardCharsets.UTF_8.name());
8443
8444            int type;
8445            while ((type = in.next()) != END_DOCUMENT) {
8446                final String tag = in.getName();
8447                if (type == START_TAG) {
8448                    if (TAG_URI_GRANT.equals(tag)) {
8449                        final int sourceUserId;
8450                        final int targetUserId;
8451                        final int userHandle = readIntAttribute(in,
8452                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8453                        if (userHandle != UserHandle.USER_NULL) {
8454                            // For backwards compatibility.
8455                            sourceUserId = userHandle;
8456                            targetUserId = userHandle;
8457                        } else {
8458                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8459                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8460                        }
8461                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8462                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8463                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8464                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8465                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8466                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8467
8468                        // Sanity check that provider still belongs to source package
8469                        final ProviderInfo pi = getProviderInfoLocked(
8470                                uri.getAuthority(), sourceUserId);
8471                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8472                            int targetUid = -1;
8473                            try {
8474                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8475                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8476                            } catch (RemoteException e) {
8477                            }
8478                            if (targetUid != -1) {
8479                                final UriPermission perm = findOrCreateUriPermissionLocked(
8480                                        sourcePkg, targetPkg, targetUid,
8481                                        new GrantUri(sourceUserId, uri, prefix));
8482                                perm.initPersistedModes(modeFlags, createdTime);
8483                            }
8484                        } else {
8485                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8486                                    + " but instead found " + pi);
8487                        }
8488                    }
8489                }
8490            }
8491        } catch (FileNotFoundException e) {
8492            // Missing grants is okay
8493        } catch (IOException e) {
8494            Slog.wtf(TAG, "Failed reading Uri grants", e);
8495        } catch (XmlPullParserException e) {
8496            Slog.wtf(TAG, "Failed reading Uri grants", e);
8497        } finally {
8498            IoUtils.closeQuietly(fis);
8499        }
8500    }
8501
8502    /**
8503     * @param uri This uri must NOT contain an embedded userId.
8504     * @param userId The userId in which the uri is to be resolved.
8505     */
8506    @Override
8507    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8508        enforceNotIsolatedCaller("takePersistableUriPermission");
8509
8510        Preconditions.checkFlagsArgument(modeFlags,
8511                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8512
8513        synchronized (this) {
8514            final int callingUid = Binder.getCallingUid();
8515            boolean persistChanged = false;
8516            GrantUri grantUri = new GrantUri(userId, uri, false);
8517
8518            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8519                    new GrantUri(userId, uri, false));
8520            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8521                    new GrantUri(userId, uri, true));
8522
8523            final boolean exactValid = (exactPerm != null)
8524                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8525            final boolean prefixValid = (prefixPerm != null)
8526                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8527
8528            if (!(exactValid || prefixValid)) {
8529                throw new SecurityException("No persistable permission grants found for UID "
8530                        + callingUid + " and Uri " + grantUri.toSafeString());
8531            }
8532
8533            if (exactValid) {
8534                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8535            }
8536            if (prefixValid) {
8537                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8538            }
8539
8540            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8541
8542            if (persistChanged) {
8543                schedulePersistUriGrants();
8544            }
8545        }
8546    }
8547
8548    /**
8549     * @param uri This uri must NOT contain an embedded userId.
8550     * @param userId The userId in which the uri is to be resolved.
8551     */
8552    @Override
8553    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8554        enforceNotIsolatedCaller("releasePersistableUriPermission");
8555
8556        Preconditions.checkFlagsArgument(modeFlags,
8557                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8558
8559        synchronized (this) {
8560            final int callingUid = Binder.getCallingUid();
8561            boolean persistChanged = false;
8562
8563            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8564                    new GrantUri(userId, uri, false));
8565            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8566                    new GrantUri(userId, uri, true));
8567            if (exactPerm == null && prefixPerm == null) {
8568                throw new SecurityException("No permission grants found for UID " + callingUid
8569                        + " and Uri " + uri.toSafeString());
8570            }
8571
8572            if (exactPerm != null) {
8573                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8574                removeUriPermissionIfNeededLocked(exactPerm);
8575            }
8576            if (prefixPerm != null) {
8577                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8578                removeUriPermissionIfNeededLocked(prefixPerm);
8579            }
8580
8581            if (persistChanged) {
8582                schedulePersistUriGrants();
8583            }
8584        }
8585    }
8586
8587    /**
8588     * Prune any older {@link UriPermission} for the given UID until outstanding
8589     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8590     *
8591     * @return if any mutations occured that require persisting.
8592     */
8593    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8594        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8595        if (perms == null) return false;
8596        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8597
8598        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8599        for (UriPermission perm : perms.values()) {
8600            if (perm.persistedModeFlags != 0) {
8601                persisted.add(perm);
8602            }
8603        }
8604
8605        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8606        if (trimCount <= 0) return false;
8607
8608        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8609        for (int i = 0; i < trimCount; i++) {
8610            final UriPermission perm = persisted.get(i);
8611
8612            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8613                    "Trimming grant created at " + perm.persistedCreateTime);
8614
8615            perm.releasePersistableModes(~0);
8616            removeUriPermissionIfNeededLocked(perm);
8617        }
8618
8619        return true;
8620    }
8621
8622    @Override
8623    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8624            String packageName, boolean incoming) {
8625        enforceNotIsolatedCaller("getPersistedUriPermissions");
8626        Preconditions.checkNotNull(packageName, "packageName");
8627
8628        final int callingUid = Binder.getCallingUid();
8629        final IPackageManager pm = AppGlobals.getPackageManager();
8630        try {
8631            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8632                    UserHandle.getUserId(callingUid));
8633            if (packageUid != callingUid) {
8634                throw new SecurityException(
8635                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8636            }
8637        } catch (RemoteException e) {
8638            throw new SecurityException("Failed to verify package name ownership");
8639        }
8640
8641        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8642        synchronized (this) {
8643            if (incoming) {
8644                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8645                        callingUid);
8646                if (perms == null) {
8647                    Slog.w(TAG, "No permission grants found for " + packageName);
8648                } else {
8649                    for (UriPermission perm : perms.values()) {
8650                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8651                            result.add(perm.buildPersistedPublicApiObject());
8652                        }
8653                    }
8654                }
8655            } else {
8656                final int size = mGrantedUriPermissions.size();
8657                for (int i = 0; i < size; i++) {
8658                    final ArrayMap<GrantUri, UriPermission> perms =
8659                            mGrantedUriPermissions.valueAt(i);
8660                    for (UriPermission perm : perms.values()) {
8661                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8662                            result.add(perm.buildPersistedPublicApiObject());
8663                        }
8664                    }
8665                }
8666            }
8667        }
8668        return new ParceledListSlice<android.content.UriPermission>(result);
8669    }
8670
8671    @Override
8672    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8673            String packageName, int userId) {
8674        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8675                "getGrantedUriPermissions");
8676
8677        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8678        synchronized (this) {
8679            final int size = mGrantedUriPermissions.size();
8680            for (int i = 0; i < size; i++) {
8681                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8682                for (UriPermission perm : perms.values()) {
8683                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8684                            && perm.persistedModeFlags != 0) {
8685                        result.add(perm.buildPersistedPublicApiObject());
8686                    }
8687                }
8688            }
8689        }
8690        return new ParceledListSlice<android.content.UriPermission>(result);
8691    }
8692
8693    @Override
8694    public void clearGrantedUriPermissions(String packageName, int userId) {
8695        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8696                "clearGrantedUriPermissions");
8697        removeUriPermissionsForPackageLocked(packageName, userId, true);
8698    }
8699
8700    @Override
8701    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8702        synchronized (this) {
8703            ProcessRecord app =
8704                who != null ? getRecordForAppLocked(who) : null;
8705            if (app == null) return;
8706
8707            Message msg = Message.obtain();
8708            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8709            msg.obj = app;
8710            msg.arg1 = waiting ? 1 : 0;
8711            mUiHandler.sendMessage(msg);
8712        }
8713    }
8714
8715    @Override
8716    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8717        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8718        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8719        outInfo.availMem = Process.getFreeMemory();
8720        outInfo.totalMem = Process.getTotalMemory();
8721        outInfo.threshold = homeAppMem;
8722        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8723        outInfo.hiddenAppThreshold = cachedAppMem;
8724        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8725                ProcessList.SERVICE_ADJ);
8726        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8727                ProcessList.VISIBLE_APP_ADJ);
8728        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8729                ProcessList.FOREGROUND_APP_ADJ);
8730    }
8731
8732    // =========================================================
8733    // TASK MANAGEMENT
8734    // =========================================================
8735
8736    @Override
8737    public List<IAppTask> getAppTasks(String callingPackage) {
8738        int callingUid = Binder.getCallingUid();
8739        long ident = Binder.clearCallingIdentity();
8740
8741        synchronized(this) {
8742            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8743            try {
8744                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8745
8746                final int N = mRecentTasks.size();
8747                for (int i = 0; i < N; i++) {
8748                    TaskRecord tr = mRecentTasks.get(i);
8749                    // Skip tasks that do not match the caller.  We don't need to verify
8750                    // callingPackage, because we are also limiting to callingUid and know
8751                    // that will limit to the correct security sandbox.
8752                    if (tr.effectiveUid != callingUid) {
8753                        continue;
8754                    }
8755                    Intent intent = tr.getBaseIntent();
8756                    if (intent == null ||
8757                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8758                        continue;
8759                    }
8760                    ActivityManager.RecentTaskInfo taskInfo =
8761                            createRecentTaskInfoFromTaskRecord(tr);
8762                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8763                    list.add(taskImpl);
8764                }
8765            } finally {
8766                Binder.restoreCallingIdentity(ident);
8767            }
8768            return list;
8769        }
8770    }
8771
8772    @Override
8773    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8774        final int callingUid = Binder.getCallingUid();
8775        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8776
8777        synchronized(this) {
8778            if (DEBUG_ALL) Slog.v(
8779                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8780
8781            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8782                    callingUid);
8783
8784            // TODO: Improve with MRU list from all ActivityStacks.
8785            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8786        }
8787
8788        return list;
8789    }
8790
8791    /**
8792     * Creates a new RecentTaskInfo from a TaskRecord.
8793     */
8794    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8795        // Update the task description to reflect any changes in the task stack
8796        tr.updateTaskDescription();
8797
8798        // Compose the recent task info
8799        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8800        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8801        rti.persistentId = tr.taskId;
8802        rti.baseIntent = new Intent(tr.getBaseIntent());
8803        rti.origActivity = tr.origActivity;
8804        rti.realActivity = tr.realActivity;
8805        rti.description = tr.lastDescription;
8806        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8807        rti.userId = tr.userId;
8808        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8809        rti.firstActiveTime = tr.firstActiveTime;
8810        rti.lastActiveTime = tr.lastActiveTime;
8811        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8812        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8813        rti.numActivities = 0;
8814        if (tr.mBounds != null) {
8815            rti.bounds = new Rect(tr.mBounds);
8816        }
8817        rti.isDockable = tr.canGoInDockedStack();
8818        rti.resizeMode = tr.mResizeMode;
8819
8820        ActivityRecord base = null;
8821        ActivityRecord top = null;
8822        ActivityRecord tmp;
8823
8824        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8825            tmp = tr.mActivities.get(i);
8826            if (tmp.finishing) {
8827                continue;
8828            }
8829            base = tmp;
8830            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8831                top = base;
8832            }
8833            rti.numActivities++;
8834        }
8835
8836        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8837        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8838
8839        return rti;
8840    }
8841
8842    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8843        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8844                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8845        if (!allowed) {
8846            if (checkPermission(android.Manifest.permission.GET_TASKS,
8847                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8848                // Temporary compatibility: some existing apps on the system image may
8849                // still be requesting the old permission and not switched to the new
8850                // one; if so, we'll still allow them full access.  This means we need
8851                // to see if they are holding the old permission and are a system app.
8852                try {
8853                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8854                        allowed = true;
8855                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8856                                + " is using old GET_TASKS but privileged; allowing");
8857                    }
8858                } catch (RemoteException e) {
8859                }
8860            }
8861        }
8862        if (!allowed) {
8863            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8864                    + " does not hold REAL_GET_TASKS; limiting output");
8865        }
8866        return allowed;
8867    }
8868
8869    @Override
8870    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8871        final int callingUid = Binder.getCallingUid();
8872        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8873                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8874
8875        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8876        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8877        synchronized (this) {
8878            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8879                    callingUid);
8880            final boolean detailed = checkCallingPermission(
8881                    android.Manifest.permission.GET_DETAILED_TASKS)
8882                    == PackageManager.PERMISSION_GRANTED;
8883
8884            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8885                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8886                return Collections.emptyList();
8887            }
8888            mRecentTasks.loadUserRecentsLocked(userId);
8889
8890            final int recentsCount = mRecentTasks.size();
8891            ArrayList<ActivityManager.RecentTaskInfo> res =
8892                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8893
8894            final Set<Integer> includedUsers;
8895            if (includeProfiles) {
8896                includedUsers = mUserController.getProfileIds(userId);
8897            } else {
8898                includedUsers = new HashSet<>();
8899            }
8900            includedUsers.add(Integer.valueOf(userId));
8901
8902            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8903                TaskRecord tr = mRecentTasks.get(i);
8904                // Only add calling user or related users recent tasks
8905                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8906                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8907                    continue;
8908                }
8909
8910                if (tr.realActivitySuspended) {
8911                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8912                    continue;
8913                }
8914
8915                // Return the entry if desired by the caller.  We always return
8916                // the first entry, because callers always expect this to be the
8917                // foreground app.  We may filter others if the caller has
8918                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8919                // we should exclude the entry.
8920
8921                if (i == 0
8922                        || withExcluded
8923                        || (tr.intent == null)
8924                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8925                                == 0)) {
8926                    if (!allowed) {
8927                        // If the caller doesn't have the GET_TASKS permission, then only
8928                        // allow them to see a small subset of tasks -- their own and home.
8929                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8930                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8931                            continue;
8932                        }
8933                    }
8934                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8935                        if (tr.stack != null && tr.stack.isHomeStack()) {
8936                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8937                                    "Skipping, home stack task: " + tr);
8938                            continue;
8939                        }
8940                    }
8941                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8942                        final ActivityStack stack = tr.stack;
8943                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8944                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8945                                    "Skipping, top task in docked stack: " + tr);
8946                            continue;
8947                        }
8948                    }
8949                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8950                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8951                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8952                                    "Skipping, pinned stack task: " + tr);
8953                            continue;
8954                        }
8955                    }
8956                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8957                        // Don't include auto remove tasks that are finished or finishing.
8958                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8959                                "Skipping, auto-remove without activity: " + tr);
8960                        continue;
8961                    }
8962                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8963                            && !tr.isAvailable) {
8964                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8965                                "Skipping, unavail real act: " + tr);
8966                        continue;
8967                    }
8968
8969                    if (!tr.mUserSetupComplete) {
8970                        // Don't include task launched while user is not done setting-up.
8971                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8972                                "Skipping, user setup not complete: " + tr);
8973                        continue;
8974                    }
8975
8976                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8977                    if (!detailed) {
8978                        rti.baseIntent.replaceExtras((Bundle)null);
8979                    }
8980
8981                    res.add(rti);
8982                    maxNum--;
8983                }
8984            }
8985            return res;
8986        }
8987    }
8988
8989    @Override
8990    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8991        synchronized (this) {
8992            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8993                    "getTaskThumbnail()");
8994            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8995                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8996            if (tr != null) {
8997                return tr.getTaskThumbnailLocked();
8998            }
8999        }
9000        return null;
9001    }
9002
9003    @Override
9004    public int addAppTask(IBinder activityToken, Intent intent,
9005            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9006        final int callingUid = Binder.getCallingUid();
9007        final long callingIdent = Binder.clearCallingIdentity();
9008
9009        try {
9010            synchronized (this) {
9011                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9012                if (r == null) {
9013                    throw new IllegalArgumentException("Activity does not exist; token="
9014                            + activityToken);
9015                }
9016                ComponentName comp = intent.getComponent();
9017                if (comp == null) {
9018                    throw new IllegalArgumentException("Intent " + intent
9019                            + " must specify explicit component");
9020                }
9021                if (thumbnail.getWidth() != mThumbnailWidth
9022                        || thumbnail.getHeight() != mThumbnailHeight) {
9023                    throw new IllegalArgumentException("Bad thumbnail size: got "
9024                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9025                            + mThumbnailWidth + "x" + mThumbnailHeight);
9026                }
9027                if (intent.getSelector() != null) {
9028                    intent.setSelector(null);
9029                }
9030                if (intent.getSourceBounds() != null) {
9031                    intent.setSourceBounds(null);
9032                }
9033                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9034                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9035                        // The caller has added this as an auto-remove task...  that makes no
9036                        // sense, so turn off auto-remove.
9037                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9038                    }
9039                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9040                    // Must be a new task.
9041                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9042                }
9043                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9044                    mLastAddedTaskActivity = null;
9045                }
9046                ActivityInfo ainfo = mLastAddedTaskActivity;
9047                if (ainfo == null) {
9048                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9049                            comp, 0, UserHandle.getUserId(callingUid));
9050                    if (ainfo.applicationInfo.uid != callingUid) {
9051                        throw new SecurityException(
9052                                "Can't add task for another application: target uid="
9053                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9054                    }
9055                }
9056
9057                // Use the full screen as the context for the task thumbnail
9058                final Point displaySize = new Point();
9059                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9060                r.task.stack.getDisplaySize(displaySize);
9061                thumbnailInfo.taskWidth = displaySize.x;
9062                thumbnailInfo.taskHeight = displaySize.y;
9063                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9064
9065                TaskRecord task = new TaskRecord(this,
9066                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9067                        ainfo, intent, description, thumbnailInfo);
9068
9069                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9070                if (trimIdx >= 0) {
9071                    // If this would have caused a trim, then we'll abort because that
9072                    // means it would be added at the end of the list but then just removed.
9073                    return INVALID_TASK_ID;
9074                }
9075
9076                final int N = mRecentTasks.size();
9077                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9078                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9079                    tr.removedFromRecents();
9080                }
9081
9082                task.inRecents = true;
9083                mRecentTasks.add(task);
9084                r.task.stack.addTask(task, false, "addAppTask");
9085
9086                task.setLastThumbnailLocked(thumbnail);
9087                task.freeLastThumbnail();
9088
9089                return task.taskId;
9090            }
9091        } finally {
9092            Binder.restoreCallingIdentity(callingIdent);
9093        }
9094    }
9095
9096    @Override
9097    public Point getAppTaskThumbnailSize() {
9098        synchronized (this) {
9099            return new Point(mThumbnailWidth,  mThumbnailHeight);
9100        }
9101    }
9102
9103    @Override
9104    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9105        synchronized (this) {
9106            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9107            if (r != null) {
9108                r.setTaskDescription(td);
9109                r.task.updateTaskDescription();
9110            }
9111        }
9112    }
9113
9114    @Override
9115    public void setTaskResizeable(int taskId, int resizeableMode) {
9116        synchronized (this) {
9117            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9118                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9119            if (task == null) {
9120                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9121                return;
9122            }
9123            if (task.mResizeMode != resizeableMode) {
9124                task.mResizeMode = resizeableMode;
9125                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9126                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9127                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9128            }
9129        }
9130    }
9131
9132    @Override
9133    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9134        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9135        long ident = Binder.clearCallingIdentity();
9136        try {
9137            synchronized (this) {
9138                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9139                if (task == null) {
9140                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9141                    return;
9142                }
9143                int stackId = task.stack.mStackId;
9144                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9145                // in crop windows resize mode or if the task size is affected by the docked stack
9146                // changing size. No need to update configuration.
9147                if (bounds != null && task.inCropWindowsResizeMode()
9148                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9149                    mWindowManager.scrollTask(task.taskId, bounds);
9150                    return;
9151                }
9152
9153                // Place the task in the right stack if it isn't there already based on
9154                // the requested bounds.
9155                // The stack transition logic is:
9156                // - a null bounds on a freeform task moves that task to fullscreen
9157                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9158                //   that task to freeform
9159                // - otherwise the task is not moved
9160                if (!StackId.isTaskResizeAllowed(stackId)) {
9161                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9162                }
9163                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9164                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9165                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9166                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9167                }
9168                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9169                if (stackId != task.stack.mStackId) {
9170                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9171                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9172                    preserveWindow = false;
9173                }
9174
9175                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9176                        false /* deferResume */);
9177            }
9178        } finally {
9179            Binder.restoreCallingIdentity(ident);
9180        }
9181    }
9182
9183    @Override
9184    public Rect getTaskBounds(int taskId) {
9185        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9186        long ident = Binder.clearCallingIdentity();
9187        Rect rect = new Rect();
9188        try {
9189            synchronized (this) {
9190                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9191                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9192                if (task == null) {
9193                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9194                    return rect;
9195                }
9196                if (task.stack != null) {
9197                    // Return the bounds from window manager since it will be adjusted for various
9198                    // things like the presense of a docked stack for tasks that aren't resizeable.
9199                    mWindowManager.getTaskBounds(task.taskId, rect);
9200                } else {
9201                    // Task isn't in window manager yet since it isn't associated with a stack.
9202                    // Return the persist value from activity manager
9203                    if (task.mBounds != null) {
9204                        rect.set(task.mBounds);
9205                    } else if (task.mLastNonFullscreenBounds != null) {
9206                        rect.set(task.mLastNonFullscreenBounds);
9207                    }
9208                }
9209            }
9210        } finally {
9211            Binder.restoreCallingIdentity(ident);
9212        }
9213        return rect;
9214    }
9215
9216    @Override
9217    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9218        if (userId != UserHandle.getCallingUserId()) {
9219            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9220                    "getTaskDescriptionIcon");
9221        }
9222        final File passedIconFile = new File(filePath);
9223        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9224                passedIconFile.getName());
9225        if (!legitIconFile.getPath().equals(filePath)
9226                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9227            throw new IllegalArgumentException("Bad file path: " + filePath
9228                    + " passed for userId " + userId);
9229        }
9230        return mRecentTasks.getTaskDescriptionIcon(filePath);
9231    }
9232
9233    @Override
9234    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9235            throws RemoteException {
9236        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9237                opts.getCustomInPlaceResId() == 0) {
9238            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9239                    "with valid animation");
9240        }
9241        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9242        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9243                opts.getCustomInPlaceResId());
9244        mWindowManager.executeAppTransition();
9245    }
9246
9247    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9248            boolean removeFromRecents) {
9249        if (removeFromRecents) {
9250            mRecentTasks.remove(tr);
9251            tr.removedFromRecents();
9252        }
9253        ComponentName component = tr.getBaseIntent().getComponent();
9254        if (component == null) {
9255            Slog.w(TAG, "No component for base intent of task: " + tr);
9256            return;
9257        }
9258
9259        // Find any running services associated with this app and stop if needed.
9260        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9261
9262        if (!killProcess) {
9263            return;
9264        }
9265
9266        // Determine if the process(es) for this task should be killed.
9267        final String pkg = component.getPackageName();
9268        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9269        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9270        for (int i = 0; i < pmap.size(); i++) {
9271
9272            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9273            for (int j = 0; j < uids.size(); j++) {
9274                ProcessRecord proc = uids.valueAt(j);
9275                if (proc.userId != tr.userId) {
9276                    // Don't kill process for a different user.
9277                    continue;
9278                }
9279                if (proc == mHomeProcess) {
9280                    // Don't kill the home process along with tasks from the same package.
9281                    continue;
9282                }
9283                if (!proc.pkgList.containsKey(pkg)) {
9284                    // Don't kill process that is not associated with this task.
9285                    continue;
9286                }
9287
9288                for (int k = 0; k < proc.activities.size(); k++) {
9289                    TaskRecord otherTask = proc.activities.get(k).task;
9290                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9291                        // Don't kill process(es) that has an activity in a different task that is
9292                        // also in recents.
9293                        return;
9294                    }
9295                }
9296
9297                if (proc.foregroundServices) {
9298                    // Don't kill process(es) with foreground service.
9299                    return;
9300                }
9301
9302                // Add process to kill list.
9303                procsToKill.add(proc);
9304            }
9305        }
9306
9307        // Kill the running processes.
9308        for (int i = 0; i < procsToKill.size(); i++) {
9309            ProcessRecord pr = procsToKill.get(i);
9310            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9311                    && pr.curReceiver == null) {
9312                pr.kill("remove task", true);
9313            } else {
9314                // We delay killing processes that are not in the background or running a receiver.
9315                pr.waitingToKill = "remove task";
9316            }
9317        }
9318    }
9319
9320    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9321        // Remove all tasks with activities in the specified package from the list of recent tasks
9322        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9323            TaskRecord tr = mRecentTasks.get(i);
9324            if (tr.userId != userId) continue;
9325
9326            ComponentName cn = tr.intent.getComponent();
9327            if (cn != null && cn.getPackageName().equals(packageName)) {
9328                // If the package name matches, remove the task.
9329                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9330            }
9331        }
9332    }
9333
9334    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9335            int userId) {
9336
9337        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9338            TaskRecord tr = mRecentTasks.get(i);
9339            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9340                continue;
9341            }
9342
9343            ComponentName cn = tr.intent.getComponent();
9344            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9345                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9346            if (sameComponent) {
9347                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9348            }
9349        }
9350    }
9351
9352    /**
9353     * Removes the task with the specified task id.
9354     *
9355     * @param taskId Identifier of the task to be removed.
9356     * @param killProcess Kill any process associated with the task if possible.
9357     * @param removeFromRecents Whether to also remove the task from recents.
9358     * @return Returns true if the given task was found and removed.
9359     */
9360    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9361            boolean removeFromRecents) {
9362        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9363                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9364        if (tr != null) {
9365            tr.removeTaskActivitiesLocked();
9366            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9367            if (tr.isPersistable) {
9368                notifyTaskPersisterLocked(null, true);
9369            }
9370            return true;
9371        }
9372        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9373        return false;
9374    }
9375
9376    @Override
9377    public void removeStack(int stackId) {
9378        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9379        if (stackId == HOME_STACK_ID) {
9380            throw new IllegalArgumentException("Removing home stack is not allowed.");
9381        }
9382
9383        synchronized (this) {
9384            final long ident = Binder.clearCallingIdentity();
9385            try {
9386                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9387                if (stack == null) {
9388                    return;
9389                }
9390                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9391                for (int i = tasks.size() - 1; i >= 0; i--) {
9392                    removeTaskByIdLocked(
9393                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9394                }
9395            } finally {
9396                Binder.restoreCallingIdentity(ident);
9397            }
9398        }
9399    }
9400
9401    @Override
9402    public boolean removeTask(int taskId) {
9403        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9404        synchronized (this) {
9405            final long ident = Binder.clearCallingIdentity();
9406            try {
9407                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9408            } finally {
9409                Binder.restoreCallingIdentity(ident);
9410            }
9411        }
9412    }
9413
9414    /**
9415     * TODO: Add mController hook
9416     */
9417    @Override
9418    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9419        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9420
9421        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9422        synchronized(this) {
9423            moveTaskToFrontLocked(taskId, flags, bOptions);
9424        }
9425    }
9426
9427    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9428        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9429
9430        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9431                Binder.getCallingUid(), -1, -1, "Task to front")) {
9432            ActivityOptions.abort(options);
9433            return;
9434        }
9435        final long origId = Binder.clearCallingIdentity();
9436        try {
9437            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9438            if (task == null) {
9439                Slog.d(TAG, "Could not find task for id: "+ taskId);
9440                return;
9441            }
9442            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9443                mStackSupervisor.showLockTaskToast();
9444                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9445                return;
9446            }
9447            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9448            if (prev != null && prev.isRecentsActivity()) {
9449                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9450            }
9451            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9452                    false /* forceNonResizable */);
9453        } finally {
9454            Binder.restoreCallingIdentity(origId);
9455        }
9456        ActivityOptions.abort(options);
9457    }
9458
9459    /**
9460     * Moves an activity, and all of the other activities within the same task, to the bottom
9461     * of the history stack.  The activity's order within the task is unchanged.
9462     *
9463     * @param token A reference to the activity we wish to move
9464     * @param nonRoot If false then this only works if the activity is the root
9465     *                of a task; if true it will work for any activity in a task.
9466     * @return Returns true if the move completed, false if not.
9467     */
9468    @Override
9469    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9470        enforceNotIsolatedCaller("moveActivityTaskToBack");
9471        synchronized(this) {
9472            final long origId = Binder.clearCallingIdentity();
9473            try {
9474                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9475                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9476                if (task != null) {
9477                    if (mStackSupervisor.isLockedTask(task)) {
9478                        mStackSupervisor.showLockTaskToast();
9479                        return false;
9480                    }
9481                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9482                }
9483            } finally {
9484                Binder.restoreCallingIdentity(origId);
9485            }
9486        }
9487        return false;
9488    }
9489
9490    @Override
9491    public void moveTaskBackwards(int task) {
9492        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9493                "moveTaskBackwards()");
9494
9495        synchronized(this) {
9496            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9497                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9498                return;
9499            }
9500            final long origId = Binder.clearCallingIdentity();
9501            moveTaskBackwardsLocked(task);
9502            Binder.restoreCallingIdentity(origId);
9503        }
9504    }
9505
9506    private final void moveTaskBackwardsLocked(int task) {
9507        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9508    }
9509
9510    @Override
9511    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9512            IActivityContainerCallback callback) throws RemoteException {
9513        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9514        synchronized (this) {
9515            if (parentActivityToken == null) {
9516                throw new IllegalArgumentException("parent token must not be null");
9517            }
9518            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9519            if (r == null) {
9520                return null;
9521            }
9522            if (callback == null) {
9523                throw new IllegalArgumentException("callback must not be null");
9524            }
9525            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9526        }
9527    }
9528
9529    @Override
9530    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9531        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9532        synchronized (this) {
9533            mStackSupervisor.deleteActivityContainer(container);
9534        }
9535    }
9536
9537    @Override
9538    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9539        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9540        synchronized (this) {
9541            final int stackId = mStackSupervisor.getNextStackId();
9542            final ActivityStack stack =
9543                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9544            if (stack == null) {
9545                return null;
9546            }
9547            return stack.mActivityContainer;
9548        }
9549    }
9550
9551    @Override
9552    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9553        synchronized (this) {
9554            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9555            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9556                return stack.mActivityContainer.getDisplayId();
9557            }
9558            return Display.DEFAULT_DISPLAY;
9559        }
9560    }
9561
9562    @Override
9563    public int getActivityStackId(IBinder token) throws RemoteException {
9564        synchronized (this) {
9565            ActivityStack stack = ActivityRecord.getStackLocked(token);
9566            if (stack == null) {
9567                return INVALID_STACK_ID;
9568            }
9569            return stack.mStackId;
9570        }
9571    }
9572
9573    @Override
9574    public void exitFreeformMode(IBinder token) throws RemoteException {
9575        synchronized (this) {
9576            long ident = Binder.clearCallingIdentity();
9577            try {
9578                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9579                if (r == null) {
9580                    throw new IllegalArgumentException(
9581                            "exitFreeformMode: No activity record matching token=" + token);
9582                }
9583                final ActivityStack stack = r.getStackLocked(token);
9584                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9585                    throw new IllegalStateException(
9586                            "exitFreeformMode: You can only go fullscreen from freeform.");
9587                }
9588                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9589                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9590                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9591            } finally {
9592                Binder.restoreCallingIdentity(ident);
9593            }
9594        }
9595    }
9596
9597    @Override
9598    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9599        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9600        if (stackId == HOME_STACK_ID) {
9601            throw new IllegalArgumentException(
9602                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9603        }
9604        synchronized (this) {
9605            long ident = Binder.clearCallingIdentity();
9606            try {
9607                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9608                        + " to stackId=" + stackId + " toTop=" + toTop);
9609                if (stackId == DOCKED_STACK_ID) {
9610                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9611                            null /* initialBounds */);
9612                }
9613                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9614                        "moveTaskToStack", ANIMATE);
9615            } finally {
9616                Binder.restoreCallingIdentity(ident);
9617            }
9618        }
9619    }
9620
9621    @Override
9622    public void swapDockedAndFullscreenStack() throws RemoteException {
9623        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9624        synchronized (this) {
9625            long ident = Binder.clearCallingIdentity();
9626            try {
9627                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9628                        FULLSCREEN_WORKSPACE_STACK_ID);
9629                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9630                        : null;
9631                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9632                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9633                        : null;
9634                if (topTask == null || tasks == null || tasks.size() == 0) {
9635                    Slog.w(TAG,
9636                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9637                    return;
9638                }
9639
9640                // TODO: App transition
9641                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9642
9643                // Defer the resume so resume/pausing while moving stacks is dangerous.
9644                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9645                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9646                        ANIMATE, true /* deferResume */);
9647                final int size = tasks.size();
9648                for (int i = 0; i < size; i++) {
9649                    final int id = tasks.get(i).taskId;
9650                    if (id == topTask.taskId) {
9651                        continue;
9652                    }
9653                    mStackSupervisor.moveTaskToStackLocked(id,
9654                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9655                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9656                }
9657
9658                // Because we deferred the resume, to avoid conflicts with stack switches while
9659                // resuming, we need to do it after all the tasks are moved.
9660                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9661                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9662
9663                mWindowManager.executeAppTransition();
9664            } finally {
9665                Binder.restoreCallingIdentity(ident);
9666            }
9667        }
9668    }
9669
9670    /**
9671     * Moves the input task to the docked stack.
9672     *
9673     * @param taskId Id of task to move.
9674     * @param createMode The mode the docked stack should be created in if it doesn't exist
9675     *                   already. See
9676     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9677     *                   and
9678     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9679     * @param toTop If the task and stack should be moved to the top.
9680     * @param animate Whether we should play an animation for the moving the task
9681     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9682     *                      docked stack. Pass {@code null} to use default bounds.
9683     */
9684    @Override
9685    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9686            Rect initialBounds) {
9687        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9688        synchronized (this) {
9689            long ident = Binder.clearCallingIdentity();
9690            try {
9691                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9692                        + " to createMode=" + createMode + " toTop=" + toTop);
9693                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9694                return mStackSupervisor.moveTaskToStackLocked(
9695                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9696                        "moveTaskToDockedStack", animate);
9697            } finally {
9698                Binder.restoreCallingIdentity(ident);
9699            }
9700        }
9701    }
9702
9703    /**
9704     * Moves the top activity in the input stackId to the pinned stack.
9705     *
9706     * @param stackId Id of stack to move the top activity to pinned stack.
9707     * @param bounds Bounds to use for pinned stack.
9708     *
9709     * @return True if the top activity of the input stack was successfully moved to the pinned
9710     *          stack.
9711     */
9712    @Override
9713    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9714        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9715        synchronized (this) {
9716            if (!mSupportsPictureInPicture) {
9717                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9718                        + "Device doesn't support picture-in-pciture mode");
9719            }
9720
9721            long ident = Binder.clearCallingIdentity();
9722            try {
9723                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9724            } finally {
9725                Binder.restoreCallingIdentity(ident);
9726            }
9727        }
9728    }
9729
9730    @Override
9731    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9732            boolean preserveWindows, boolean animate, int animationDuration) {
9733        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9734        long ident = Binder.clearCallingIdentity();
9735        try {
9736            synchronized (this) {
9737                if (animate) {
9738                    if (stackId == PINNED_STACK_ID) {
9739                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9740                    } else {
9741                        throw new IllegalArgumentException("Stack: " + stackId
9742                                + " doesn't support animated resize.");
9743                    }
9744                } else {
9745                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9746                            null /* tempTaskInsetBounds */, preserveWindows,
9747                            allowResizeInDockedMode, !DEFER_RESUME);
9748                }
9749            }
9750        } finally {
9751            Binder.restoreCallingIdentity(ident);
9752        }
9753    }
9754
9755    @Override
9756    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9757            Rect tempDockedTaskInsetBounds,
9758            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9759        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9760                "resizeDockedStack()");
9761        long ident = Binder.clearCallingIdentity();
9762        try {
9763            synchronized (this) {
9764                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9765                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9766                        PRESERVE_WINDOWS);
9767            }
9768        } finally {
9769            Binder.restoreCallingIdentity(ident);
9770        }
9771    }
9772
9773    @Override
9774    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9775        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9776                "resizePinnedStack()");
9777        final long ident = Binder.clearCallingIdentity();
9778        try {
9779            synchronized (this) {
9780                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9781            }
9782        } finally {
9783            Binder.restoreCallingIdentity(ident);
9784        }
9785    }
9786
9787    @Override
9788    public void positionTaskInStack(int taskId, int stackId, int position) {
9789        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9790        if (stackId == HOME_STACK_ID) {
9791            throw new IllegalArgumentException(
9792                    "positionTaskInStack: Attempt to change the position of task "
9793                    + taskId + " in/to home stack");
9794        }
9795        synchronized (this) {
9796            long ident = Binder.clearCallingIdentity();
9797            try {
9798                if (DEBUG_STACK) Slog.d(TAG_STACK,
9799                        "positionTaskInStack: positioning task=" + taskId
9800                        + " in stackId=" + stackId + " at position=" + position);
9801                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9802            } finally {
9803                Binder.restoreCallingIdentity(ident);
9804            }
9805        }
9806    }
9807
9808    @Override
9809    public List<StackInfo> getAllStackInfos() {
9810        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9811        long ident = Binder.clearCallingIdentity();
9812        try {
9813            synchronized (this) {
9814                return mStackSupervisor.getAllStackInfosLocked();
9815            }
9816        } finally {
9817            Binder.restoreCallingIdentity(ident);
9818        }
9819    }
9820
9821    @Override
9822    public StackInfo getStackInfo(int stackId) {
9823        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9824        long ident = Binder.clearCallingIdentity();
9825        try {
9826            synchronized (this) {
9827                return mStackSupervisor.getStackInfoLocked(stackId);
9828            }
9829        } finally {
9830            Binder.restoreCallingIdentity(ident);
9831        }
9832    }
9833
9834    @Override
9835    public boolean isInHomeStack(int taskId) {
9836        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9837        long ident = Binder.clearCallingIdentity();
9838        try {
9839            synchronized (this) {
9840                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9841                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9842                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9843            }
9844        } finally {
9845            Binder.restoreCallingIdentity(ident);
9846        }
9847    }
9848
9849    @Override
9850    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9851        synchronized(this) {
9852            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9853        }
9854    }
9855
9856    @Override
9857    public void updateDeviceOwner(String packageName) {
9858        final int callingUid = Binder.getCallingUid();
9859        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9860            throw new SecurityException("updateDeviceOwner called from non-system process");
9861        }
9862        synchronized (this) {
9863            mDeviceOwnerName = packageName;
9864        }
9865    }
9866
9867    @Override
9868    public void updateLockTaskPackages(int userId, String[] packages) {
9869        final int callingUid = Binder.getCallingUid();
9870        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9871            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9872                    "updateLockTaskPackages()");
9873        }
9874        synchronized (this) {
9875            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9876                    Arrays.toString(packages));
9877            mLockTaskPackages.put(userId, packages);
9878            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9879        }
9880    }
9881
9882
9883    void startLockTaskModeLocked(TaskRecord task) {
9884        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9885        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9886            return;
9887        }
9888
9889        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9890        // is initiated by system after the pinning request was shown and locked mode is initiated
9891        // by an authorized app directly
9892        final int callingUid = Binder.getCallingUid();
9893        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9894        long ident = Binder.clearCallingIdentity();
9895        try {
9896            if (!isSystemInitiated) {
9897                task.mLockTaskUid = callingUid;
9898                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9899                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9900                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9901                    StatusBarManagerInternal statusBarManager =
9902                            LocalServices.getService(StatusBarManagerInternal.class);
9903                    if (statusBarManager != null) {
9904                        statusBarManager.showScreenPinningRequest(task.taskId);
9905                    }
9906                    return;
9907                }
9908
9909                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9910                if (stack == null || task != stack.topTask()) {
9911                    throw new IllegalArgumentException("Invalid task, not in foreground");
9912                }
9913            }
9914            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9915                    "Locking fully");
9916            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9917                    ActivityManager.LOCK_TASK_MODE_PINNED :
9918                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9919                    "startLockTask", true);
9920        } finally {
9921            Binder.restoreCallingIdentity(ident);
9922        }
9923    }
9924
9925    @Override
9926    public void startLockTaskMode(int taskId) {
9927        synchronized (this) {
9928            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9929            if (task != null) {
9930                startLockTaskModeLocked(task);
9931            }
9932        }
9933    }
9934
9935    @Override
9936    public void startLockTaskMode(IBinder token) {
9937        synchronized (this) {
9938            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9939            if (r == null) {
9940                return;
9941            }
9942            final TaskRecord task = r.task;
9943            if (task != null) {
9944                startLockTaskModeLocked(task);
9945            }
9946        }
9947    }
9948
9949    @Override
9950    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9951        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9952        // This makes inner call to look as if it was initiated by system.
9953        long ident = Binder.clearCallingIdentity();
9954        try {
9955            synchronized (this) {
9956                startLockTaskMode(taskId);
9957            }
9958        } finally {
9959            Binder.restoreCallingIdentity(ident);
9960        }
9961    }
9962
9963    @Override
9964    public void stopLockTaskMode() {
9965        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9966        if (lockTask == null) {
9967            // Our work here is done.
9968            return;
9969        }
9970
9971        final int callingUid = Binder.getCallingUid();
9972        final int lockTaskUid = lockTask.mLockTaskUid;
9973        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9974        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9975            // Done.
9976            return;
9977        } else {
9978            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9979            // It is possible lockTaskMode was started by the system process because
9980            // android:lockTaskMode is set to a locking value in the application manifest
9981            // instead of the app calling startLockTaskMode. In this case
9982            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
9983            // {@link TaskRecord.effectiveUid} instead. Also caller with
9984            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
9985            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
9986                    && callingUid != lockTaskUid
9987                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
9988                throw new SecurityException("Invalid uid, expected " + lockTaskUid
9989                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9990            }
9991        }
9992        long ident = Binder.clearCallingIdentity();
9993        try {
9994            Log.d(TAG, "stopLockTaskMode");
9995            // Stop lock task
9996            synchronized (this) {
9997                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9998                        "stopLockTask", true);
9999            }
10000        } finally {
10001            Binder.restoreCallingIdentity(ident);
10002        }
10003    }
10004
10005    /**
10006     * This API should be called by SystemUI only when user perform certain action to dismiss
10007     * lock task mode. We should only dismiss pinned lock task mode in this case.
10008     */
10009    @Override
10010    public void stopSystemLockTaskMode() throws RemoteException {
10011        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10012            stopLockTaskMode();
10013        } else {
10014            mStackSupervisor.showLockTaskToast();
10015        }
10016    }
10017
10018    @Override
10019    public boolean isInLockTaskMode() {
10020        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10021    }
10022
10023    @Override
10024    public int getLockTaskModeState() {
10025        synchronized (this) {
10026            return mStackSupervisor.getLockTaskModeState();
10027        }
10028    }
10029
10030    @Override
10031    public void showLockTaskEscapeMessage(IBinder token) {
10032        synchronized (this) {
10033            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10034            if (r == null) {
10035                return;
10036            }
10037            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10038        }
10039    }
10040
10041    // =========================================================
10042    // CONTENT PROVIDERS
10043    // =========================================================
10044
10045    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10046        List<ProviderInfo> providers = null;
10047        try {
10048            providers = AppGlobals.getPackageManager()
10049                    .queryContentProviders(app.processName, app.uid,
10050                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10051                                    | MATCH_DEBUG_TRIAGED_MISSING)
10052                    .getList();
10053        } catch (RemoteException ex) {
10054        }
10055        if (DEBUG_MU) Slog.v(TAG_MU,
10056                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10057        int userId = app.userId;
10058        if (providers != null) {
10059            int N = providers.size();
10060            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10061            for (int i=0; i<N; i++) {
10062                ProviderInfo cpi =
10063                    (ProviderInfo)providers.get(i);
10064                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10065                        cpi.name, cpi.flags);
10066                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10067                    // This is a singleton provider, but a user besides the
10068                    // default user is asking to initialize a process it runs
10069                    // in...  well, no, it doesn't actually run in this process,
10070                    // it runs in the process of the default user.  Get rid of it.
10071                    providers.remove(i);
10072                    N--;
10073                    i--;
10074                    continue;
10075                }
10076
10077                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10078                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10079                if (cpr == null) {
10080                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10081                    mProviderMap.putProviderByClass(comp, cpr);
10082                }
10083                if (DEBUG_MU) Slog.v(TAG_MU,
10084                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10085                app.pubProviders.put(cpi.name, cpr);
10086                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10087                    // Don't add this if it is a platform component that is marked
10088                    // to run in multiple processes, because this is actually
10089                    // part of the framework so doesn't make sense to track as a
10090                    // separate apk in the process.
10091                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10092                            mProcessStats);
10093                }
10094                notifyPackageUse(cpi.applicationInfo.packageName);
10095            }
10096        }
10097        return providers;
10098    }
10099
10100    /**
10101     * Check if {@link ProcessRecord} has a possible chance at accessing the
10102     * given {@link ProviderInfo}. Final permission checking is always done
10103     * in {@link ContentProvider}.
10104     */
10105    private final String checkContentProviderPermissionLocked(
10106            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10107        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10108        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10109        boolean checkedGrants = false;
10110        if (checkUser) {
10111            // Looking for cross-user grants before enforcing the typical cross-users permissions
10112            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10113            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10114                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10115                    return null;
10116                }
10117                checkedGrants = true;
10118            }
10119            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10120                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10121            if (userId != tmpTargetUserId) {
10122                // When we actually went to determine the final targer user ID, this ended
10123                // up different than our initial check for the authority.  This is because
10124                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10125                // SELF.  So we need to re-check the grants again.
10126                checkedGrants = false;
10127            }
10128        }
10129        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10130                cpi.applicationInfo.uid, cpi.exported)
10131                == PackageManager.PERMISSION_GRANTED) {
10132            return null;
10133        }
10134        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10135                cpi.applicationInfo.uid, cpi.exported)
10136                == PackageManager.PERMISSION_GRANTED) {
10137            return null;
10138        }
10139
10140        PathPermission[] pps = cpi.pathPermissions;
10141        if (pps != null) {
10142            int i = pps.length;
10143            while (i > 0) {
10144                i--;
10145                PathPermission pp = pps[i];
10146                String pprperm = pp.getReadPermission();
10147                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10148                        cpi.applicationInfo.uid, cpi.exported)
10149                        == PackageManager.PERMISSION_GRANTED) {
10150                    return null;
10151                }
10152                String ppwperm = pp.getWritePermission();
10153                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10154                        cpi.applicationInfo.uid, cpi.exported)
10155                        == PackageManager.PERMISSION_GRANTED) {
10156                    return null;
10157                }
10158            }
10159        }
10160        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10161            return null;
10162        }
10163
10164        String msg;
10165        if (!cpi.exported) {
10166            msg = "Permission Denial: opening provider " + cpi.name
10167                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10168                    + ", uid=" + callingUid + ") that is not exported from uid "
10169                    + cpi.applicationInfo.uid;
10170        } else {
10171            msg = "Permission Denial: opening provider " + cpi.name
10172                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10173                    + ", uid=" + callingUid + ") requires "
10174                    + cpi.readPermission + " or " + cpi.writePermission;
10175        }
10176        Slog.w(TAG, msg);
10177        return msg;
10178    }
10179
10180    /**
10181     * Returns if the ContentProvider has granted a uri to callingUid
10182     */
10183    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10184        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10185        if (perms != null) {
10186            for (int i=perms.size()-1; i>=0; i--) {
10187                GrantUri grantUri = perms.keyAt(i);
10188                if (grantUri.sourceUserId == userId || !checkUser) {
10189                    if (matchesProvider(grantUri.uri, cpi)) {
10190                        return true;
10191                    }
10192                }
10193            }
10194        }
10195        return false;
10196    }
10197
10198    /**
10199     * Returns true if the uri authority is one of the authorities specified in the provider.
10200     */
10201    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10202        String uriAuth = uri.getAuthority();
10203        String cpiAuth = cpi.authority;
10204        if (cpiAuth.indexOf(';') == -1) {
10205            return cpiAuth.equals(uriAuth);
10206        }
10207        String[] cpiAuths = cpiAuth.split(";");
10208        int length = cpiAuths.length;
10209        for (int i = 0; i < length; i++) {
10210            if (cpiAuths[i].equals(uriAuth)) return true;
10211        }
10212        return false;
10213    }
10214
10215    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10216            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10217        if (r != null) {
10218            for (int i=0; i<r.conProviders.size(); i++) {
10219                ContentProviderConnection conn = r.conProviders.get(i);
10220                if (conn.provider == cpr) {
10221                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10222                            "Adding provider requested by "
10223                            + r.processName + " from process "
10224                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10225                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10226                    if (stable) {
10227                        conn.stableCount++;
10228                        conn.numStableIncs++;
10229                    } else {
10230                        conn.unstableCount++;
10231                        conn.numUnstableIncs++;
10232                    }
10233                    return conn;
10234                }
10235            }
10236            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10237            if (stable) {
10238                conn.stableCount = 1;
10239                conn.numStableIncs = 1;
10240            } else {
10241                conn.unstableCount = 1;
10242                conn.numUnstableIncs = 1;
10243            }
10244            cpr.connections.add(conn);
10245            r.conProviders.add(conn);
10246            startAssociationLocked(r.uid, r.processName, r.curProcState,
10247                    cpr.uid, cpr.name, cpr.info.processName);
10248            return conn;
10249        }
10250        cpr.addExternalProcessHandleLocked(externalProcessToken);
10251        return null;
10252    }
10253
10254    boolean decProviderCountLocked(ContentProviderConnection conn,
10255            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10256        if (conn != null) {
10257            cpr = conn.provider;
10258            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10259                    "Removing provider requested by "
10260                    + conn.client.processName + " from process "
10261                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10262                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10263            if (stable) {
10264                conn.stableCount--;
10265            } else {
10266                conn.unstableCount--;
10267            }
10268            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10269                cpr.connections.remove(conn);
10270                conn.client.conProviders.remove(conn);
10271                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10272                    // The client is more important than last activity -- note the time this
10273                    // is happening, so we keep the old provider process around a bit as last
10274                    // activity to avoid thrashing it.
10275                    if (cpr.proc != null) {
10276                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10277                    }
10278                }
10279                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10280                return true;
10281            }
10282            return false;
10283        }
10284        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10285        return false;
10286    }
10287
10288    private void checkTime(long startTime, String where) {
10289        long now = SystemClock.elapsedRealtime();
10290        if ((now-startTime) > 1000) {
10291            // If we are taking more than a second, log about it.
10292            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10293        }
10294    }
10295
10296    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10297            String name, IBinder token, boolean stable, int userId) {
10298        ContentProviderRecord cpr;
10299        ContentProviderConnection conn = null;
10300        ProviderInfo cpi = null;
10301
10302        synchronized(this) {
10303            long startTime = SystemClock.elapsedRealtime();
10304
10305            ProcessRecord r = null;
10306            if (caller != null) {
10307                r = getRecordForAppLocked(caller);
10308                if (r == null) {
10309                    throw new SecurityException(
10310                            "Unable to find app for caller " + caller
10311                          + " (pid=" + Binder.getCallingPid()
10312                          + ") when getting content provider " + name);
10313                }
10314            }
10315
10316            boolean checkCrossUser = true;
10317
10318            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10319
10320            // First check if this content provider has been published...
10321            cpr = mProviderMap.getProviderByName(name, userId);
10322            // If that didn't work, check if it exists for user 0 and then
10323            // verify that it's a singleton provider before using it.
10324            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10325                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10326                if (cpr != null) {
10327                    cpi = cpr.info;
10328                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10329                            cpi.name, cpi.flags)
10330                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10331                        userId = UserHandle.USER_SYSTEM;
10332                        checkCrossUser = false;
10333                    } else {
10334                        cpr = null;
10335                        cpi = null;
10336                    }
10337                }
10338            }
10339
10340            boolean providerRunning = cpr != null;
10341            if (providerRunning) {
10342                cpi = cpr.info;
10343                String msg;
10344                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10345                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10346                        != null) {
10347                    throw new SecurityException(msg);
10348                }
10349                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10350
10351                if (r != null && cpr.canRunHere(r)) {
10352                    // This provider has been published or is in the process
10353                    // of being published...  but it is also allowed to run
10354                    // in the caller's process, so don't make a connection
10355                    // and just let the caller instantiate its own instance.
10356                    ContentProviderHolder holder = cpr.newHolder(null);
10357                    // don't give caller the provider object, it needs
10358                    // to make its own.
10359                    holder.provider = null;
10360                    return holder;
10361                }
10362
10363                final long origId = Binder.clearCallingIdentity();
10364
10365                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10366
10367                // In this case the provider instance already exists, so we can
10368                // return it right away.
10369                conn = incProviderCountLocked(r, cpr, token, stable);
10370                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10371                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10372                        // If this is a perceptible app accessing the provider,
10373                        // make sure to count it as being accessed and thus
10374                        // back up on the LRU list.  This is good because
10375                        // content providers are often expensive to start.
10376                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10377                        updateLruProcessLocked(cpr.proc, false, null);
10378                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10379                    }
10380                }
10381
10382                if (cpr.proc != null) {
10383                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10384                    boolean success = updateOomAdjLocked(cpr.proc);
10385                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10386                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10387                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10388                    // NOTE: there is still a race here where a signal could be
10389                    // pending on the process even though we managed to update its
10390                    // adj level.  Not sure what to do about this, but at least
10391                    // the race is now smaller.
10392                    if (!success) {
10393                        // Uh oh...  it looks like the provider's process
10394                        // has been killed on us.  We need to wait for a new
10395                        // process to be started, and make sure its death
10396                        // doesn't kill our process.
10397                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10398                                + " is crashing; detaching " + r);
10399                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10400                        checkTime(startTime, "getContentProviderImpl: before appDied");
10401                        appDiedLocked(cpr.proc);
10402                        checkTime(startTime, "getContentProviderImpl: after appDied");
10403                        if (!lastRef) {
10404                            // This wasn't the last ref our process had on
10405                            // the provider...  we have now been killed, bail.
10406                            return null;
10407                        }
10408                        providerRunning = false;
10409                        conn = null;
10410                    }
10411                }
10412
10413                Binder.restoreCallingIdentity(origId);
10414            }
10415
10416            if (!providerRunning) {
10417                try {
10418                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10419                    cpi = AppGlobals.getPackageManager().
10420                        resolveContentProvider(name,
10421                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10422                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10423                } catch (RemoteException ex) {
10424                }
10425                if (cpi == null) {
10426                    return null;
10427                }
10428                // If the provider is a singleton AND
10429                // (it's a call within the same user || the provider is a
10430                // privileged app)
10431                // Then allow connecting to the singleton provider
10432                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10433                        cpi.name, cpi.flags)
10434                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10435                if (singleton) {
10436                    userId = UserHandle.USER_SYSTEM;
10437                }
10438                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10439                checkTime(startTime, "getContentProviderImpl: got app info for user");
10440
10441                String msg;
10442                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10443                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10444                        != null) {
10445                    throw new SecurityException(msg);
10446                }
10447                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10448
10449                if (!mProcessesReady
10450                        && !cpi.processName.equals("system")) {
10451                    // If this content provider does not run in the system
10452                    // process, and the system is not yet ready to run other
10453                    // processes, then fail fast instead of hanging.
10454                    throw new IllegalArgumentException(
10455                            "Attempt to launch content provider before system ready");
10456                }
10457
10458                // Make sure that the user who owns this provider is running.  If not,
10459                // we don't want to allow it to run.
10460                if (!mUserController.isUserRunningLocked(userId, 0)) {
10461                    Slog.w(TAG, "Unable to launch app "
10462                            + cpi.applicationInfo.packageName + "/"
10463                            + cpi.applicationInfo.uid + " for provider "
10464                            + name + ": user " + userId + " is stopped");
10465                    return null;
10466                }
10467
10468                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10469                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10470                cpr = mProviderMap.getProviderByClass(comp, userId);
10471                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10472                final boolean firstClass = cpr == null;
10473                if (firstClass) {
10474                    final long ident = Binder.clearCallingIdentity();
10475
10476                    // If permissions need a review before any of the app components can run,
10477                    // we return no provider and launch a review activity if the calling app
10478                    // is in the foreground.
10479                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10480                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10481                            return null;
10482                        }
10483                    }
10484
10485                    try {
10486                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10487                        ApplicationInfo ai =
10488                            AppGlobals.getPackageManager().
10489                                getApplicationInfo(
10490                                        cpi.applicationInfo.packageName,
10491                                        STOCK_PM_FLAGS, userId);
10492                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10493                        if (ai == null) {
10494                            Slog.w(TAG, "No package info for content provider "
10495                                    + cpi.name);
10496                            return null;
10497                        }
10498                        ai = getAppInfoForUser(ai, userId);
10499                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10500                    } catch (RemoteException ex) {
10501                        // pm is in same process, this will never happen.
10502                    } finally {
10503                        Binder.restoreCallingIdentity(ident);
10504                    }
10505                }
10506
10507                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10508
10509                if (r != null && cpr.canRunHere(r)) {
10510                    // If this is a multiprocess provider, then just return its
10511                    // info and allow the caller to instantiate it.  Only do
10512                    // this if the provider is the same user as the caller's
10513                    // process, or can run as root (so can be in any process).
10514                    return cpr.newHolder(null);
10515                }
10516
10517                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10518                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10519                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10520
10521                // This is single process, and our app is now connecting to it.
10522                // See if we are already in the process of launching this
10523                // provider.
10524                final int N = mLaunchingProviders.size();
10525                int i;
10526                for (i = 0; i < N; i++) {
10527                    if (mLaunchingProviders.get(i) == cpr) {
10528                        break;
10529                    }
10530                }
10531
10532                // If the provider is not already being launched, then get it
10533                // started.
10534                if (i >= N) {
10535                    final long origId = Binder.clearCallingIdentity();
10536
10537                    try {
10538                        // Content provider is now in use, its package can't be stopped.
10539                        try {
10540                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10541                            AppGlobals.getPackageManager().setPackageStoppedState(
10542                                    cpr.appInfo.packageName, false, userId);
10543                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10544                        } catch (RemoteException e) {
10545                        } catch (IllegalArgumentException e) {
10546                            Slog.w(TAG, "Failed trying to unstop package "
10547                                    + cpr.appInfo.packageName + ": " + e);
10548                        }
10549
10550                        // Use existing process if already started
10551                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10552                        ProcessRecord proc = getProcessRecordLocked(
10553                                cpi.processName, cpr.appInfo.uid, false);
10554                        if (proc != null && proc.thread != null) {
10555                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10556                                    "Installing in existing process " + proc);
10557                            if (!proc.pubProviders.containsKey(cpi.name)) {
10558                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10559                                proc.pubProviders.put(cpi.name, cpr);
10560                                try {
10561                                    proc.thread.scheduleInstallProvider(cpi);
10562                                } catch (RemoteException e) {
10563                                }
10564                            }
10565                        } else {
10566                            checkTime(startTime, "getContentProviderImpl: before start process");
10567                            proc = startProcessLocked(cpi.processName,
10568                                    cpr.appInfo, false, 0, "content provider",
10569                                    new ComponentName(cpi.applicationInfo.packageName,
10570                                            cpi.name), false, false, false);
10571                            checkTime(startTime, "getContentProviderImpl: after start process");
10572                            if (proc == null) {
10573                                Slog.w(TAG, "Unable to launch app "
10574                                        + cpi.applicationInfo.packageName + "/"
10575                                        + cpi.applicationInfo.uid + " for provider "
10576                                        + name + ": process is bad");
10577                                return null;
10578                            }
10579                        }
10580                        cpr.launchingApp = proc;
10581                        mLaunchingProviders.add(cpr);
10582                    } finally {
10583                        Binder.restoreCallingIdentity(origId);
10584                    }
10585                }
10586
10587                checkTime(startTime, "getContentProviderImpl: updating data structures");
10588
10589                // Make sure the provider is published (the same provider class
10590                // may be published under multiple names).
10591                if (firstClass) {
10592                    mProviderMap.putProviderByClass(comp, cpr);
10593                }
10594
10595                mProviderMap.putProviderByName(name, cpr);
10596                conn = incProviderCountLocked(r, cpr, token, stable);
10597                if (conn != null) {
10598                    conn.waiting = true;
10599                }
10600            }
10601            checkTime(startTime, "getContentProviderImpl: done!");
10602        }
10603
10604        // Wait for the provider to be published...
10605        synchronized (cpr) {
10606            while (cpr.provider == null) {
10607                if (cpr.launchingApp == null) {
10608                    Slog.w(TAG, "Unable to launch app "
10609                            + cpi.applicationInfo.packageName + "/"
10610                            + cpi.applicationInfo.uid + " for provider "
10611                            + name + ": launching app became null");
10612                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10613                            UserHandle.getUserId(cpi.applicationInfo.uid),
10614                            cpi.applicationInfo.packageName,
10615                            cpi.applicationInfo.uid, name);
10616                    return null;
10617                }
10618                try {
10619                    if (DEBUG_MU) Slog.v(TAG_MU,
10620                            "Waiting to start provider " + cpr
10621                            + " launchingApp=" + cpr.launchingApp);
10622                    if (conn != null) {
10623                        conn.waiting = true;
10624                    }
10625                    cpr.wait();
10626                } catch (InterruptedException ex) {
10627                } finally {
10628                    if (conn != null) {
10629                        conn.waiting = false;
10630                    }
10631                }
10632            }
10633        }
10634        return cpr != null ? cpr.newHolder(conn) : null;
10635    }
10636
10637    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10638            ProcessRecord r, final int userId) {
10639        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10640                cpi.packageName, userId)) {
10641
10642            final boolean callerForeground = r == null || r.setSchedGroup
10643                    != ProcessList.SCHED_GROUP_BACKGROUND;
10644
10645            // Show a permission review UI only for starting from a foreground app
10646            if (!callerForeground) {
10647                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10648                        + cpi.packageName + " requires a permissions review");
10649                return false;
10650            }
10651
10652            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10653            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10654                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10655            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10656
10657            if (DEBUG_PERMISSIONS_REVIEW) {
10658                Slog.i(TAG, "u" + userId + " Launching permission review "
10659                        + "for package " + cpi.packageName);
10660            }
10661
10662            final UserHandle userHandle = new UserHandle(userId);
10663            mHandler.post(new Runnable() {
10664                @Override
10665                public void run() {
10666                    mContext.startActivityAsUser(intent, userHandle);
10667                }
10668            });
10669
10670            return false;
10671        }
10672
10673        return true;
10674    }
10675
10676    PackageManagerInternal getPackageManagerInternalLocked() {
10677        if (mPackageManagerInt == null) {
10678            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10679        }
10680        return mPackageManagerInt;
10681    }
10682
10683    @Override
10684    public final ContentProviderHolder getContentProvider(
10685            IApplicationThread caller, String name, int userId, boolean stable) {
10686        enforceNotIsolatedCaller("getContentProvider");
10687        if (caller == null) {
10688            String msg = "null IApplicationThread when getting content provider "
10689                    + name;
10690            Slog.w(TAG, msg);
10691            throw new SecurityException(msg);
10692        }
10693        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10694        // with cross-user grant.
10695        return getContentProviderImpl(caller, name, null, stable, userId);
10696    }
10697
10698    public ContentProviderHolder getContentProviderExternal(
10699            String name, int userId, IBinder token) {
10700        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10701            "Do not have permission in call getContentProviderExternal()");
10702        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10703                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10704        return getContentProviderExternalUnchecked(name, token, userId);
10705    }
10706
10707    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10708            IBinder token, int userId) {
10709        return getContentProviderImpl(null, name, token, true, userId);
10710    }
10711
10712    /**
10713     * Drop a content provider from a ProcessRecord's bookkeeping
10714     */
10715    public void removeContentProvider(IBinder connection, boolean stable) {
10716        enforceNotIsolatedCaller("removeContentProvider");
10717        long ident = Binder.clearCallingIdentity();
10718        try {
10719            synchronized (this) {
10720                ContentProviderConnection conn;
10721                try {
10722                    conn = (ContentProviderConnection)connection;
10723                } catch (ClassCastException e) {
10724                    String msg ="removeContentProvider: " + connection
10725                            + " not a ContentProviderConnection";
10726                    Slog.w(TAG, msg);
10727                    throw new IllegalArgumentException(msg);
10728                }
10729                if (conn == null) {
10730                    throw new NullPointerException("connection is null");
10731                }
10732                if (decProviderCountLocked(conn, null, null, stable)) {
10733                    updateOomAdjLocked();
10734                }
10735            }
10736        } finally {
10737            Binder.restoreCallingIdentity(ident);
10738        }
10739    }
10740
10741    public void removeContentProviderExternal(String name, IBinder token) {
10742        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10743            "Do not have permission in call removeContentProviderExternal()");
10744        int userId = UserHandle.getCallingUserId();
10745        long ident = Binder.clearCallingIdentity();
10746        try {
10747            removeContentProviderExternalUnchecked(name, token, userId);
10748        } finally {
10749            Binder.restoreCallingIdentity(ident);
10750        }
10751    }
10752
10753    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10754        synchronized (this) {
10755            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10756            if(cpr == null) {
10757                //remove from mProvidersByClass
10758                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10759                return;
10760            }
10761
10762            //update content provider record entry info
10763            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10764            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10765            if (localCpr.hasExternalProcessHandles()) {
10766                if (localCpr.removeExternalProcessHandleLocked(token)) {
10767                    updateOomAdjLocked();
10768                } else {
10769                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10770                            + " with no external reference for token: "
10771                            + token + ".");
10772                }
10773            } else {
10774                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10775                        + " with no external references.");
10776            }
10777        }
10778    }
10779
10780    public final void publishContentProviders(IApplicationThread caller,
10781            List<ContentProviderHolder> providers) {
10782        if (providers == null) {
10783            return;
10784        }
10785
10786        enforceNotIsolatedCaller("publishContentProviders");
10787        synchronized (this) {
10788            final ProcessRecord r = getRecordForAppLocked(caller);
10789            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10790            if (r == null) {
10791                throw new SecurityException(
10792                        "Unable to find app for caller " + caller
10793                      + " (pid=" + Binder.getCallingPid()
10794                      + ") when publishing content providers");
10795            }
10796
10797            final long origId = Binder.clearCallingIdentity();
10798
10799            final int N = providers.size();
10800            for (int i = 0; i < N; i++) {
10801                ContentProviderHolder src = providers.get(i);
10802                if (src == null || src.info == null || src.provider == null) {
10803                    continue;
10804                }
10805                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10806                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10807                if (dst != null) {
10808                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10809                    mProviderMap.putProviderByClass(comp, dst);
10810                    String names[] = dst.info.authority.split(";");
10811                    for (int j = 0; j < names.length; j++) {
10812                        mProviderMap.putProviderByName(names[j], dst);
10813                    }
10814
10815                    int launchingCount = mLaunchingProviders.size();
10816                    int j;
10817                    boolean wasInLaunchingProviders = false;
10818                    for (j = 0; j < launchingCount; j++) {
10819                        if (mLaunchingProviders.get(j) == dst) {
10820                            mLaunchingProviders.remove(j);
10821                            wasInLaunchingProviders = true;
10822                            j--;
10823                            launchingCount--;
10824                        }
10825                    }
10826                    if (wasInLaunchingProviders) {
10827                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10828                    }
10829                    synchronized (dst) {
10830                        dst.provider = src.provider;
10831                        dst.proc = r;
10832                        dst.notifyAll();
10833                    }
10834                    updateOomAdjLocked(r);
10835                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10836                            src.info.authority);
10837                }
10838            }
10839
10840            Binder.restoreCallingIdentity(origId);
10841        }
10842    }
10843
10844    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10845        ContentProviderConnection conn;
10846        try {
10847            conn = (ContentProviderConnection)connection;
10848        } catch (ClassCastException e) {
10849            String msg ="refContentProvider: " + connection
10850                    + " not a ContentProviderConnection";
10851            Slog.w(TAG, msg);
10852            throw new IllegalArgumentException(msg);
10853        }
10854        if (conn == null) {
10855            throw new NullPointerException("connection is null");
10856        }
10857
10858        synchronized (this) {
10859            if (stable > 0) {
10860                conn.numStableIncs += stable;
10861            }
10862            stable = conn.stableCount + stable;
10863            if (stable < 0) {
10864                throw new IllegalStateException("stableCount < 0: " + stable);
10865            }
10866
10867            if (unstable > 0) {
10868                conn.numUnstableIncs += unstable;
10869            }
10870            unstable = conn.unstableCount + unstable;
10871            if (unstable < 0) {
10872                throw new IllegalStateException("unstableCount < 0: " + unstable);
10873            }
10874
10875            if ((stable+unstable) <= 0) {
10876                throw new IllegalStateException("ref counts can't go to zero here: stable="
10877                        + stable + " unstable=" + unstable);
10878            }
10879            conn.stableCount = stable;
10880            conn.unstableCount = unstable;
10881            return !conn.dead;
10882        }
10883    }
10884
10885    public void unstableProviderDied(IBinder connection) {
10886        ContentProviderConnection conn;
10887        try {
10888            conn = (ContentProviderConnection)connection;
10889        } catch (ClassCastException e) {
10890            String msg ="refContentProvider: " + connection
10891                    + " not a ContentProviderConnection";
10892            Slog.w(TAG, msg);
10893            throw new IllegalArgumentException(msg);
10894        }
10895        if (conn == null) {
10896            throw new NullPointerException("connection is null");
10897        }
10898
10899        // Safely retrieve the content provider associated with the connection.
10900        IContentProvider provider;
10901        synchronized (this) {
10902            provider = conn.provider.provider;
10903        }
10904
10905        if (provider == null) {
10906            // Um, yeah, we're way ahead of you.
10907            return;
10908        }
10909
10910        // Make sure the caller is being honest with us.
10911        if (provider.asBinder().pingBinder()) {
10912            // Er, no, still looks good to us.
10913            synchronized (this) {
10914                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10915                        + " says " + conn + " died, but we don't agree");
10916                return;
10917            }
10918        }
10919
10920        // Well look at that!  It's dead!
10921        synchronized (this) {
10922            if (conn.provider.provider != provider) {
10923                // But something changed...  good enough.
10924                return;
10925            }
10926
10927            ProcessRecord proc = conn.provider.proc;
10928            if (proc == null || proc.thread == null) {
10929                // Seems like the process is already cleaned up.
10930                return;
10931            }
10932
10933            // As far as we're concerned, this is just like receiving a
10934            // death notification...  just a bit prematurely.
10935            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10936                    + ") early provider death");
10937            final long ident = Binder.clearCallingIdentity();
10938            try {
10939                appDiedLocked(proc);
10940            } finally {
10941                Binder.restoreCallingIdentity(ident);
10942            }
10943        }
10944    }
10945
10946    @Override
10947    public void appNotRespondingViaProvider(IBinder connection) {
10948        enforceCallingPermission(
10949                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10950
10951        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10952        if (conn == null) {
10953            Slog.w(TAG, "ContentProviderConnection is null");
10954            return;
10955        }
10956
10957        final ProcessRecord host = conn.provider.proc;
10958        if (host == null) {
10959            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10960            return;
10961        }
10962
10963        mHandler.post(new Runnable() {
10964            @Override
10965            public void run() {
10966                mAppErrors.appNotResponding(host, null, null, false,
10967                        "ContentProvider not responding");
10968            }
10969        });
10970    }
10971
10972    public final void installSystemProviders() {
10973        List<ProviderInfo> providers;
10974        synchronized (this) {
10975            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10976            providers = generateApplicationProvidersLocked(app);
10977            if (providers != null) {
10978                for (int i=providers.size()-1; i>=0; i--) {
10979                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10980                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10981                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10982                                + ": not system .apk");
10983                        providers.remove(i);
10984                    }
10985                }
10986            }
10987        }
10988        if (providers != null) {
10989            mSystemThread.installSystemProviders(providers);
10990        }
10991
10992        mCoreSettingsObserver = new CoreSettingsObserver(this);
10993        mFontScaleSettingObserver = new FontScaleSettingObserver();
10994
10995        //mUsageStatsService.monitorPackages();
10996    }
10997
10998    private void startPersistentApps(int matchFlags) {
10999        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11000
11001        synchronized (this) {
11002            try {
11003                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11004                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11005                for (ApplicationInfo app : apps) {
11006                    if (!"android".equals(app.packageName)) {
11007                        addAppLocked(app, false, null /* ABI override */);
11008                    }
11009                }
11010            } catch (RemoteException ex) {
11011            }
11012        }
11013    }
11014
11015    /**
11016     * When a user is unlocked, we need to install encryption-unaware providers
11017     * belonging to any running apps.
11018     */
11019    private void installEncryptionUnawareProviders(int userId) {
11020        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
11021            // TODO: eventually pivot this back to look at current user state,
11022            // similar to the comment in UserManager.isUserUnlocked(), but for
11023            // now, if we started apps when "unlocked" then unaware providers
11024            // have already been spun up.
11025            return;
11026        }
11027
11028        // We're only interested in providers that are encryption unaware, and
11029        // we don't care about uninstalled apps, since there's no way they're
11030        // running at this point.
11031        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11032
11033        synchronized (this) {
11034            final int NP = mProcessNames.getMap().size();
11035            for (int ip = 0; ip < NP; ip++) {
11036                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11037                final int NA = apps.size();
11038                for (int ia = 0; ia < NA; ia++) {
11039                    final ProcessRecord app = apps.valueAt(ia);
11040                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11041
11042                    final int NG = app.pkgList.size();
11043                    for (int ig = 0; ig < NG; ig++) {
11044                        try {
11045                            final String pkgName = app.pkgList.keyAt(ig);
11046                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11047                                    .getPackageInfo(pkgName, matchFlags, userId);
11048                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11049                                for (ProviderInfo provInfo : pkgInfo.providers) {
11050                                    Log.v(TAG, "Installing " + provInfo);
11051                                    app.thread.scheduleInstallProvider(provInfo);
11052                                }
11053                            }
11054                        } catch (RemoteException ignored) {
11055                        }
11056                    }
11057                }
11058            }
11059        }
11060    }
11061
11062    /**
11063     * Allows apps to retrieve the MIME type of a URI.
11064     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11065     * users, then it does not need permission to access the ContentProvider.
11066     * Either, it needs cross-user uri grants.
11067     *
11068     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11069     *
11070     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11071     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11072     */
11073    public String getProviderMimeType(Uri uri, int userId) {
11074        enforceNotIsolatedCaller("getProviderMimeType");
11075        final String name = uri.getAuthority();
11076        int callingUid = Binder.getCallingUid();
11077        int callingPid = Binder.getCallingPid();
11078        long ident = 0;
11079        boolean clearedIdentity = false;
11080        synchronized (this) {
11081            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11082        }
11083        if (canClearIdentity(callingPid, callingUid, userId)) {
11084            clearedIdentity = true;
11085            ident = Binder.clearCallingIdentity();
11086        }
11087        ContentProviderHolder holder = null;
11088        try {
11089            holder = getContentProviderExternalUnchecked(name, null, userId);
11090            if (holder != null) {
11091                return holder.provider.getType(uri);
11092            }
11093        } catch (RemoteException e) {
11094            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11095            return null;
11096        } finally {
11097            // We need to clear the identity to call removeContentProviderExternalUnchecked
11098            if (!clearedIdentity) {
11099                ident = Binder.clearCallingIdentity();
11100            }
11101            try {
11102                if (holder != null) {
11103                    removeContentProviderExternalUnchecked(name, null, userId);
11104                }
11105            } finally {
11106                Binder.restoreCallingIdentity(ident);
11107            }
11108        }
11109
11110        return null;
11111    }
11112
11113    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11114        if (UserHandle.getUserId(callingUid) == userId) {
11115            return true;
11116        }
11117        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11118                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11119                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11120                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11121                return true;
11122        }
11123        return false;
11124    }
11125
11126    // =========================================================
11127    // GLOBAL MANAGEMENT
11128    // =========================================================
11129
11130    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11131            boolean isolated, int isolatedUid) {
11132        String proc = customProcess != null ? customProcess : info.processName;
11133        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11134        final int userId = UserHandle.getUserId(info.uid);
11135        int uid = info.uid;
11136        if (isolated) {
11137            if (isolatedUid == 0) {
11138                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11139                while (true) {
11140                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11141                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11142                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11143                    }
11144                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11145                    mNextIsolatedProcessUid++;
11146                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11147                        // No process for this uid, use it.
11148                        break;
11149                    }
11150                    stepsLeft--;
11151                    if (stepsLeft <= 0) {
11152                        return null;
11153                    }
11154                }
11155            } else {
11156                // Special case for startIsolatedProcess (internal only), where
11157                // the uid of the isolated process is specified by the caller.
11158                uid = isolatedUid;
11159            }
11160        }
11161        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11162        if (!mBooted && !mBooting
11163                && userId == UserHandle.USER_SYSTEM
11164                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11165            r.persistent = true;
11166        }
11167        addProcessNameLocked(r);
11168        return r;
11169    }
11170
11171    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11172            String abiOverride) {
11173        ProcessRecord app;
11174        if (!isolated) {
11175            app = getProcessRecordLocked(info.processName, info.uid, true);
11176        } else {
11177            app = null;
11178        }
11179
11180        if (app == null) {
11181            app = newProcessRecordLocked(info, null, isolated, 0);
11182            updateLruProcessLocked(app, false, null);
11183            updateOomAdjLocked();
11184        }
11185
11186        // This package really, really can not be stopped.
11187        try {
11188            AppGlobals.getPackageManager().setPackageStoppedState(
11189                    info.packageName, false, UserHandle.getUserId(app.uid));
11190        } catch (RemoteException e) {
11191        } catch (IllegalArgumentException e) {
11192            Slog.w(TAG, "Failed trying to unstop package "
11193                    + info.packageName + ": " + e);
11194        }
11195
11196        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11197            app.persistent = true;
11198            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11199        }
11200        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11201            mPersistentStartingProcesses.add(app);
11202            startProcessLocked(app, "added application", app.processName, abiOverride,
11203                    null /* entryPoint */, null /* entryPointArgs */);
11204        }
11205
11206        return app;
11207    }
11208
11209    public void unhandledBack() {
11210        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11211                "unhandledBack()");
11212
11213        synchronized(this) {
11214            final long origId = Binder.clearCallingIdentity();
11215            try {
11216                getFocusedStack().unhandledBackLocked();
11217            } finally {
11218                Binder.restoreCallingIdentity(origId);
11219            }
11220        }
11221    }
11222
11223    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11224        enforceNotIsolatedCaller("openContentUri");
11225        final int userId = UserHandle.getCallingUserId();
11226        String name = uri.getAuthority();
11227        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11228        ParcelFileDescriptor pfd = null;
11229        if (cph != null) {
11230            // We record the binder invoker's uid in thread-local storage before
11231            // going to the content provider to open the file.  Later, in the code
11232            // that handles all permissions checks, we look for this uid and use
11233            // that rather than the Activity Manager's own uid.  The effect is that
11234            // we do the check against the caller's permissions even though it looks
11235            // to the content provider like the Activity Manager itself is making
11236            // the request.
11237            Binder token = new Binder();
11238            sCallerIdentity.set(new Identity(
11239                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11240            try {
11241                pfd = cph.provider.openFile(null, uri, "r", null, token);
11242            } catch (FileNotFoundException e) {
11243                // do nothing; pfd will be returned null
11244            } finally {
11245                // Ensure that whatever happens, we clean up the identity state
11246                sCallerIdentity.remove();
11247                // Ensure we're done with the provider.
11248                removeContentProviderExternalUnchecked(name, null, userId);
11249            }
11250        } else {
11251            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11252        }
11253        return pfd;
11254    }
11255
11256    // Actually is sleeping or shutting down or whatever else in the future
11257    // is an inactive state.
11258    public boolean isSleepingOrShuttingDown() {
11259        return isSleeping() || mShuttingDown;
11260    }
11261
11262    public boolean isSleeping() {
11263        return mSleeping;
11264    }
11265
11266    void onWakefulnessChanged(int wakefulness) {
11267        synchronized(this) {
11268            mWakefulness = wakefulness;
11269            updateSleepIfNeededLocked();
11270        }
11271    }
11272
11273    void finishRunningVoiceLocked() {
11274        if (mRunningVoice != null) {
11275            mRunningVoice = null;
11276            mVoiceWakeLock.release();
11277            updateSleepIfNeededLocked();
11278        }
11279    }
11280
11281    void startTimeTrackingFocusedActivityLocked() {
11282        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11283            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11284        }
11285    }
11286
11287    void updateSleepIfNeededLocked() {
11288        if (mSleeping && !shouldSleepLocked()) {
11289            mSleeping = false;
11290            startTimeTrackingFocusedActivityLocked();
11291            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11292            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11293            updateOomAdjLocked();
11294        } else if (!mSleeping && shouldSleepLocked()) {
11295            mSleeping = true;
11296            if (mCurAppTimeTracker != null) {
11297                mCurAppTimeTracker.stop();
11298            }
11299            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11300            mStackSupervisor.goingToSleepLocked();
11301            updateOomAdjLocked();
11302
11303            // Initialize the wake times of all processes.
11304            checkExcessivePowerUsageLocked(false);
11305            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11306            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11307            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11308        }
11309    }
11310
11311    private boolean shouldSleepLocked() {
11312        // Resume applications while running a voice interactor.
11313        if (mRunningVoice != null) {
11314            return false;
11315        }
11316
11317        // TODO: Transform the lock screen state into a sleep token instead.
11318        switch (mWakefulness) {
11319            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11320            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11321            case PowerManagerInternal.WAKEFULNESS_DOZING:
11322                // Pause applications whenever the lock screen is shown or any sleep
11323                // tokens have been acquired.
11324                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11325            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11326            default:
11327                // If we're asleep then pause applications unconditionally.
11328                return true;
11329        }
11330    }
11331
11332    /** Pokes the task persister. */
11333    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11334        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11335    }
11336
11337    /** Notifies all listeners when the task stack has changed. */
11338    void notifyTaskStackChangedLocked() {
11339        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11340        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11341        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11342        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11343    }
11344
11345    /** Notifies all listeners when an Activity is pinned. */
11346    void notifyActivityPinnedLocked() {
11347        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11348        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11349    }
11350
11351    /**
11352     * Notifies all listeners when an attempt was made to start an an activity that is already
11353     * running in the pinned stack and the activity was not actually started, but the task is
11354     * either brought to the front or a new Intent is delivered to it.
11355     */
11356    void notifyPinnedActivityRestartAttemptLocked() {
11357        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11358        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11359    }
11360
11361    /** Notifies all listeners when the pinned stack animation ends. */
11362    @Override
11363    public void notifyPinnedStackAnimationEnded() {
11364        synchronized (this) {
11365            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11366            mHandler.obtainMessage(
11367                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11368        }
11369    }
11370
11371    @Override
11372    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11373        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11374    }
11375
11376    @Override
11377    public boolean shutdown(int timeout) {
11378        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11379                != PackageManager.PERMISSION_GRANTED) {
11380            throw new SecurityException("Requires permission "
11381                    + android.Manifest.permission.SHUTDOWN);
11382        }
11383
11384        boolean timedout = false;
11385
11386        synchronized(this) {
11387            mShuttingDown = true;
11388            updateEventDispatchingLocked();
11389            timedout = mStackSupervisor.shutdownLocked(timeout);
11390        }
11391
11392        mAppOpsService.shutdown();
11393        if (mUsageStatsService != null) {
11394            mUsageStatsService.prepareShutdown();
11395        }
11396        mBatteryStatsService.shutdown();
11397        synchronized (this) {
11398            mProcessStats.shutdownLocked();
11399            notifyTaskPersisterLocked(null, true);
11400        }
11401
11402        return timedout;
11403    }
11404
11405    public final void activitySlept(IBinder token) {
11406        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11407
11408        final long origId = Binder.clearCallingIdentity();
11409
11410        synchronized (this) {
11411            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11412            if (r != null) {
11413                mStackSupervisor.activitySleptLocked(r);
11414            }
11415        }
11416
11417        Binder.restoreCallingIdentity(origId);
11418    }
11419
11420    private String lockScreenShownToString() {
11421        switch (mLockScreenShown) {
11422            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11423            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11424            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11425            default: return "Unknown=" + mLockScreenShown;
11426        }
11427    }
11428
11429    void logLockScreen(String msg) {
11430        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11431                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11432                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11433                + " mSleeping=" + mSleeping);
11434    }
11435
11436    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11437        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11438        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11439        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11440            boolean wasRunningVoice = mRunningVoice != null;
11441            mRunningVoice = session;
11442            if (!wasRunningVoice) {
11443                mVoiceWakeLock.acquire();
11444                updateSleepIfNeededLocked();
11445            }
11446        }
11447    }
11448
11449    private void updateEventDispatchingLocked() {
11450        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11451    }
11452
11453    public void setLockScreenShown(boolean shown) {
11454        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11455                != PackageManager.PERMISSION_GRANTED) {
11456            throw new SecurityException("Requires permission "
11457                    + android.Manifest.permission.DEVICE_POWER);
11458        }
11459
11460        synchronized(this) {
11461            long ident = Binder.clearCallingIdentity();
11462            try {
11463                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11464                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11465                updateSleepIfNeededLocked();
11466            } finally {
11467                Binder.restoreCallingIdentity(ident);
11468            }
11469        }
11470    }
11471
11472    @Override
11473    public void notifyLockedProfile(@UserIdInt int userId) {
11474        try {
11475            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11476                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11477            }
11478        } catch (RemoteException ex) {
11479            throw new SecurityException("Fail to check is caller a privileged app", ex);
11480        }
11481
11482        synchronized (this) {
11483            if (mStackSupervisor.isUserLockedProfile(userId)) {
11484                final long ident = Binder.clearCallingIdentity();
11485                try {
11486                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11487                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11488                        // If there is no device lock, we will show the profile's credential page.
11489                        mActivityStarter.showConfirmDeviceCredential(userId);
11490                    } else {
11491                        // Showing launcher to avoid user entering credential twice.
11492                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11493                    }
11494                } finally {
11495                    Binder.restoreCallingIdentity(ident);
11496                }
11497            }
11498        }
11499    }
11500
11501    @Override
11502    public void stopAppSwitches() {
11503        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11504                != PackageManager.PERMISSION_GRANTED) {
11505            throw new SecurityException("viewquires permission "
11506                    + android.Manifest.permission.STOP_APP_SWITCHES);
11507        }
11508
11509        synchronized(this) {
11510            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11511                    + APP_SWITCH_DELAY_TIME;
11512            mDidAppSwitch = false;
11513            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11514            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11515            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11516        }
11517    }
11518
11519    public void resumeAppSwitches() {
11520        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11521                != PackageManager.PERMISSION_GRANTED) {
11522            throw new SecurityException("Requires permission "
11523                    + android.Manifest.permission.STOP_APP_SWITCHES);
11524        }
11525
11526        synchronized(this) {
11527            // Note that we don't execute any pending app switches... we will
11528            // let those wait until either the timeout, or the next start
11529            // activity request.
11530            mAppSwitchesAllowedTime = 0;
11531        }
11532    }
11533
11534    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11535            int callingPid, int callingUid, String name) {
11536        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11537            return true;
11538        }
11539
11540        int perm = checkComponentPermission(
11541                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11542                sourceUid, -1, true);
11543        if (perm == PackageManager.PERMISSION_GRANTED) {
11544            return true;
11545        }
11546
11547        // If the actual IPC caller is different from the logical source, then
11548        // also see if they are allowed to control app switches.
11549        if (callingUid != -1 && callingUid != sourceUid) {
11550            perm = checkComponentPermission(
11551                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11552                    callingUid, -1, true);
11553            if (perm == PackageManager.PERMISSION_GRANTED) {
11554                return true;
11555            }
11556        }
11557
11558        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11559        return false;
11560    }
11561
11562    public void setDebugApp(String packageName, boolean waitForDebugger,
11563            boolean persistent) {
11564        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11565                "setDebugApp()");
11566
11567        long ident = Binder.clearCallingIdentity();
11568        try {
11569            // Note that this is not really thread safe if there are multiple
11570            // callers into it at the same time, but that's not a situation we
11571            // care about.
11572            if (persistent) {
11573                final ContentResolver resolver = mContext.getContentResolver();
11574                Settings.Global.putString(
11575                    resolver, Settings.Global.DEBUG_APP,
11576                    packageName);
11577                Settings.Global.putInt(
11578                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11579                    waitForDebugger ? 1 : 0);
11580            }
11581
11582            synchronized (this) {
11583                if (!persistent) {
11584                    mOrigDebugApp = mDebugApp;
11585                    mOrigWaitForDebugger = mWaitForDebugger;
11586                }
11587                mDebugApp = packageName;
11588                mWaitForDebugger = waitForDebugger;
11589                mDebugTransient = !persistent;
11590                if (packageName != null) {
11591                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11592                            false, UserHandle.USER_ALL, "set debug app");
11593                }
11594            }
11595        } finally {
11596            Binder.restoreCallingIdentity(ident);
11597        }
11598    }
11599
11600    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11601        synchronized (this) {
11602            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11603            if (!isDebuggable) {
11604                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11605                    throw new SecurityException("Process not debuggable: " + app.packageName);
11606                }
11607            }
11608
11609            mTrackAllocationApp = processName;
11610        }
11611    }
11612
11613    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11614        synchronized (this) {
11615            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11616            if (!isDebuggable) {
11617                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11618                    throw new SecurityException("Process not debuggable: " + app.packageName);
11619                }
11620            }
11621            mProfileApp = processName;
11622            mProfileFile = profilerInfo.profileFile;
11623            if (mProfileFd != null) {
11624                try {
11625                    mProfileFd.close();
11626                } catch (IOException e) {
11627                }
11628                mProfileFd = null;
11629            }
11630            mProfileFd = profilerInfo.profileFd;
11631            mSamplingInterval = profilerInfo.samplingInterval;
11632            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11633            mProfileType = 0;
11634        }
11635    }
11636
11637    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11638        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11639        if (!isDebuggable) {
11640            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11641                throw new SecurityException("Process not debuggable: " + app.packageName);
11642            }
11643        }
11644        mNativeDebuggingApp = processName;
11645    }
11646
11647    @Override
11648    public void setAlwaysFinish(boolean enabled) {
11649        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11650                "setAlwaysFinish()");
11651
11652        long ident = Binder.clearCallingIdentity();
11653        try {
11654            Settings.Global.putInt(
11655                    mContext.getContentResolver(),
11656                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11657
11658            synchronized (this) {
11659                mAlwaysFinishActivities = enabled;
11660            }
11661        } finally {
11662            Binder.restoreCallingIdentity(ident);
11663        }
11664    }
11665
11666    @Override
11667    public void setLenientBackgroundCheck(boolean enabled) {
11668        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11669                "setLenientBackgroundCheck()");
11670
11671        long ident = Binder.clearCallingIdentity();
11672        try {
11673            Settings.Global.putInt(
11674                    mContext.getContentResolver(),
11675                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11676
11677            synchronized (this) {
11678                mLenientBackgroundCheck = enabled;
11679            }
11680        } finally {
11681            Binder.restoreCallingIdentity(ident);
11682        }
11683    }
11684
11685    @Override
11686    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11687        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11688                "setActivityController()");
11689        synchronized (this) {
11690            mController = controller;
11691            mControllerIsAMonkey = imAMonkey;
11692            Watchdog.getInstance().setActivityController(controller);
11693        }
11694    }
11695
11696    @Override
11697    public void setUserIsMonkey(boolean userIsMonkey) {
11698        synchronized (this) {
11699            synchronized (mPidsSelfLocked) {
11700                final int callingPid = Binder.getCallingPid();
11701                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11702                if (precessRecord == null) {
11703                    throw new SecurityException("Unknown process: " + callingPid);
11704                }
11705                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11706                    throw new SecurityException("Only an instrumentation process "
11707                            + "with a UiAutomation can call setUserIsMonkey");
11708                }
11709            }
11710            mUserIsMonkey = userIsMonkey;
11711        }
11712    }
11713
11714    @Override
11715    public boolean isUserAMonkey() {
11716        synchronized (this) {
11717            // If there is a controller also implies the user is a monkey.
11718            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11719        }
11720    }
11721
11722    public void requestBugReport(int bugreportType) {
11723        String service = null;
11724        switch (bugreportType) {
11725            case ActivityManager.BUGREPORT_OPTION_FULL:
11726                service = "bugreport";
11727                break;
11728            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11729                service = "bugreportplus";
11730                break;
11731            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11732                service = "bugreportremote";
11733                break;
11734        }
11735        if (service == null) {
11736            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11737                    + bugreportType);
11738        }
11739        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11740        SystemProperties.set("ctl.start", service);
11741    }
11742
11743    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11744        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11745    }
11746
11747    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11748        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11749            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11750        }
11751        return KEY_DISPATCHING_TIMEOUT;
11752    }
11753
11754    @Override
11755    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11756        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11757                != PackageManager.PERMISSION_GRANTED) {
11758            throw new SecurityException("Requires permission "
11759                    + android.Manifest.permission.FILTER_EVENTS);
11760        }
11761        ProcessRecord proc;
11762        long timeout;
11763        synchronized (this) {
11764            synchronized (mPidsSelfLocked) {
11765                proc = mPidsSelfLocked.get(pid);
11766            }
11767            timeout = getInputDispatchingTimeoutLocked(proc);
11768        }
11769
11770        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11771            return -1;
11772        }
11773
11774        return timeout;
11775    }
11776
11777    /**
11778     * Handle input dispatching timeouts.
11779     * Returns whether input dispatching should be aborted or not.
11780     */
11781    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11782            final ActivityRecord activity, final ActivityRecord parent,
11783            final boolean aboveSystem, String reason) {
11784        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11785                != PackageManager.PERMISSION_GRANTED) {
11786            throw new SecurityException("Requires permission "
11787                    + android.Manifest.permission.FILTER_EVENTS);
11788        }
11789
11790        final String annotation;
11791        if (reason == null) {
11792            annotation = "Input dispatching timed out";
11793        } else {
11794            annotation = "Input dispatching timed out (" + reason + ")";
11795        }
11796
11797        if (proc != null) {
11798            synchronized (this) {
11799                if (proc.debugging) {
11800                    return false;
11801                }
11802
11803                if (mDidDexOpt) {
11804                    // Give more time since we were dexopting.
11805                    mDidDexOpt = false;
11806                    return false;
11807                }
11808
11809                if (proc.instrumentationClass != null) {
11810                    Bundle info = new Bundle();
11811                    info.putString("shortMsg", "keyDispatchingTimedOut");
11812                    info.putString("longMsg", annotation);
11813                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11814                    return true;
11815                }
11816            }
11817            mHandler.post(new Runnable() {
11818                @Override
11819                public void run() {
11820                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11821                }
11822            });
11823        }
11824
11825        return true;
11826    }
11827
11828    @Override
11829    public Bundle getAssistContextExtras(int requestType) {
11830        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11831                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11832        if (pae == null) {
11833            return null;
11834        }
11835        synchronized (pae) {
11836            while (!pae.haveResult) {
11837                try {
11838                    pae.wait();
11839                } catch (InterruptedException e) {
11840                }
11841            }
11842        }
11843        synchronized (this) {
11844            buildAssistBundleLocked(pae, pae.result);
11845            mPendingAssistExtras.remove(pae);
11846            mUiHandler.removeCallbacks(pae);
11847        }
11848        return pae.extras;
11849    }
11850
11851    @Override
11852    public boolean isAssistDataAllowedOnCurrentActivity() {
11853        int userId;
11854        synchronized (this) {
11855            userId = mUserController.getCurrentUserIdLocked();
11856            ActivityRecord activity = getFocusedStack().topActivity();
11857            if (activity == null) {
11858                return false;
11859            }
11860            userId = activity.userId;
11861        }
11862        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11863                Context.DEVICE_POLICY_SERVICE);
11864        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11865    }
11866
11867    @Override
11868    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11869        long ident = Binder.clearCallingIdentity();
11870        try {
11871            synchronized (this) {
11872                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11873                ActivityRecord top = getFocusedStack().topActivity();
11874                if (top != caller) {
11875                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11876                            + " is not current top " + top);
11877                    return false;
11878                }
11879                if (!top.nowVisible) {
11880                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11881                            + " is not visible");
11882                    return false;
11883                }
11884            }
11885            AssistUtils utils = new AssistUtils(mContext);
11886            return utils.showSessionForActiveService(args,
11887                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11888        } finally {
11889            Binder.restoreCallingIdentity(ident);
11890        }
11891    }
11892
11893    @Override
11894    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11895            Bundle receiverExtras,
11896            IBinder activityToken, boolean focused) {
11897        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11898                activityToken, focused,
11899                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11900                != null;
11901    }
11902
11903    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11904            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11905            int userHandle, Bundle args, long timeout) {
11906        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11907                "enqueueAssistContext()");
11908        synchronized (this) {
11909            ActivityRecord activity = getFocusedStack().topActivity();
11910            if (activity == null) {
11911                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11912                return null;
11913            }
11914            if (activity.app == null || activity.app.thread == null) {
11915                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11916                return null;
11917            }
11918            if (focused) {
11919                if (activityToken != null) {
11920                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11921                    if (activity != caller) {
11922                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11923                                + " is not current top " + activity);
11924                        return null;
11925                    }
11926                }
11927            } else {
11928                activity = ActivityRecord.forTokenLocked(activityToken);
11929                if (activity == null) {
11930                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11931                            + " couldn't be found");
11932                    return null;
11933                }
11934            }
11935
11936            PendingAssistExtras pae;
11937            Bundle extras = new Bundle();
11938            if (args != null) {
11939                extras.putAll(args);
11940            }
11941            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11942            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11943            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11944                    userHandle);
11945            try {
11946                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11947                        requestType);
11948                mPendingAssistExtras.add(pae);
11949                mUiHandler.postDelayed(pae, timeout);
11950            } catch (RemoteException e) {
11951                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11952                return null;
11953            }
11954            return pae;
11955        }
11956    }
11957
11958    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11959        IResultReceiver receiver;
11960        synchronized (this) {
11961            mPendingAssistExtras.remove(pae);
11962            receiver = pae.receiver;
11963        }
11964        if (receiver != null) {
11965            // Caller wants result sent back to them.
11966            try {
11967                pae.receiver.send(0, null);
11968            } catch (RemoteException e) {
11969            }
11970        }
11971    }
11972
11973    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11974        if (result != null) {
11975            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11976        }
11977        if (pae.hint != null) {
11978            pae.extras.putBoolean(pae.hint, true);
11979        }
11980    }
11981
11982    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11983            AssistContent content, Uri referrer) {
11984        PendingAssistExtras pae = (PendingAssistExtras)token;
11985        synchronized (pae) {
11986            pae.result = extras;
11987            pae.structure = structure;
11988            pae.content = content;
11989            if (referrer != null) {
11990                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11991            }
11992            pae.haveResult = true;
11993            pae.notifyAll();
11994            if (pae.intent == null && pae.receiver == null) {
11995                // Caller is just waiting for the result.
11996                return;
11997            }
11998        }
11999
12000        // We are now ready to launch the assist activity.
12001        IResultReceiver sendReceiver = null;
12002        Bundle sendBundle = null;
12003        synchronized (this) {
12004            buildAssistBundleLocked(pae, extras);
12005            boolean exists = mPendingAssistExtras.remove(pae);
12006            mUiHandler.removeCallbacks(pae);
12007            if (!exists) {
12008                // Timed out.
12009                return;
12010            }
12011            if ((sendReceiver=pae.receiver) != null) {
12012                // Caller wants result sent back to them.
12013                sendBundle = new Bundle();
12014                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12015                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12016                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12017                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12018                        pae.receiverExtras);
12019            }
12020        }
12021        if (sendReceiver != null) {
12022            try {
12023                sendReceiver.send(0, sendBundle);
12024            } catch (RemoteException e) {
12025            }
12026            return;
12027        }
12028
12029        long ident = Binder.clearCallingIdentity();
12030        try {
12031            pae.intent.replaceExtras(pae.extras);
12032            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12033                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12034                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12035            closeSystemDialogs("assist");
12036            try {
12037                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12038            } catch (ActivityNotFoundException e) {
12039                Slog.w(TAG, "No activity to handle assist action.", e);
12040            }
12041        } finally {
12042            Binder.restoreCallingIdentity(ident);
12043        }
12044    }
12045
12046    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12047            Bundle args) {
12048        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12049                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12050    }
12051
12052    public void registerProcessObserver(IProcessObserver observer) {
12053        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12054                "registerProcessObserver()");
12055        synchronized (this) {
12056            mProcessObservers.register(observer);
12057        }
12058    }
12059
12060    @Override
12061    public void unregisterProcessObserver(IProcessObserver observer) {
12062        synchronized (this) {
12063            mProcessObservers.unregister(observer);
12064        }
12065    }
12066
12067    @Override
12068    public void registerUidObserver(IUidObserver observer, int which) {
12069        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12070                "registerUidObserver()");
12071        synchronized (this) {
12072            mUidObservers.register(observer, which);
12073        }
12074    }
12075
12076    @Override
12077    public void unregisterUidObserver(IUidObserver observer) {
12078        synchronized (this) {
12079            mUidObservers.unregister(observer);
12080        }
12081    }
12082
12083    @Override
12084    public boolean convertFromTranslucent(IBinder token) {
12085        final long origId = Binder.clearCallingIdentity();
12086        try {
12087            synchronized (this) {
12088                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12089                if (r == null) {
12090                    return false;
12091                }
12092                final boolean translucentChanged = r.changeWindowTranslucency(true);
12093                if (translucentChanged) {
12094                    r.task.stack.releaseBackgroundResources(r);
12095                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12096                }
12097                mWindowManager.setAppFullscreen(token, true);
12098                return translucentChanged;
12099            }
12100        } finally {
12101            Binder.restoreCallingIdentity(origId);
12102        }
12103    }
12104
12105    @Override
12106    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12107        final long origId = Binder.clearCallingIdentity();
12108        try {
12109            synchronized (this) {
12110                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12111                if (r == null) {
12112                    return false;
12113                }
12114                int index = r.task.mActivities.lastIndexOf(r);
12115                if (index > 0) {
12116                    ActivityRecord under = r.task.mActivities.get(index - 1);
12117                    under.returningOptions = options;
12118                }
12119                final boolean translucentChanged = r.changeWindowTranslucency(false);
12120                if (translucentChanged) {
12121                    r.task.stack.convertActivityToTranslucent(r);
12122                }
12123                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12124                mWindowManager.setAppFullscreen(token, false);
12125                return translucentChanged;
12126            }
12127        } finally {
12128            Binder.restoreCallingIdentity(origId);
12129        }
12130    }
12131
12132    @Override
12133    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12134        final long origId = Binder.clearCallingIdentity();
12135        try {
12136            synchronized (this) {
12137                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12138                if (r != null) {
12139                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12140                }
12141            }
12142            return false;
12143        } finally {
12144            Binder.restoreCallingIdentity(origId);
12145        }
12146    }
12147
12148    @Override
12149    public boolean isBackgroundVisibleBehind(IBinder token) {
12150        final long origId = Binder.clearCallingIdentity();
12151        try {
12152            synchronized (this) {
12153                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12154                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12155                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12156                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12157                return visible;
12158            }
12159        } finally {
12160            Binder.restoreCallingIdentity(origId);
12161        }
12162    }
12163
12164    @Override
12165    public ActivityOptions getActivityOptions(IBinder token) {
12166        final long origId = Binder.clearCallingIdentity();
12167        try {
12168            synchronized (this) {
12169                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12170                if (r != null) {
12171                    final ActivityOptions activityOptions = r.pendingOptions;
12172                    r.pendingOptions = null;
12173                    return activityOptions;
12174                }
12175                return null;
12176            }
12177        } finally {
12178            Binder.restoreCallingIdentity(origId);
12179        }
12180    }
12181
12182    @Override
12183    public void setImmersive(IBinder token, boolean immersive) {
12184        synchronized(this) {
12185            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12186            if (r == null) {
12187                throw new IllegalArgumentException();
12188            }
12189            r.immersive = immersive;
12190
12191            // update associated state if we're frontmost
12192            if (r == mFocusedActivity) {
12193                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12194                applyUpdateLockStateLocked(r);
12195            }
12196        }
12197    }
12198
12199    @Override
12200    public boolean isImmersive(IBinder token) {
12201        synchronized (this) {
12202            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12203            if (r == null) {
12204                throw new IllegalArgumentException();
12205            }
12206            return r.immersive;
12207        }
12208    }
12209
12210    @Override
12211    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12212        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12213            throw new UnsupportedOperationException("VR mode not supported on this device!");
12214        }
12215
12216        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12217
12218        ActivityRecord r;
12219        synchronized (this) {
12220            r = ActivityRecord.isInStackLocked(token);
12221        }
12222
12223        if (r == null) {
12224            throw new IllegalArgumentException();
12225        }
12226
12227        int err;
12228        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12229                VrManagerInternal.NO_ERROR) {
12230            return err;
12231        }
12232
12233        synchronized(this) {
12234            r.requestedVrComponent = (enabled) ? packageName : null;
12235
12236            // Update associated state if this activity is currently focused
12237            if (r == mFocusedActivity) {
12238                applyUpdateVrModeLocked(r);
12239            }
12240            return 0;
12241        }
12242    }
12243
12244    @Override
12245    public boolean isVrModePackageEnabled(ComponentName packageName) {
12246        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12247            throw new UnsupportedOperationException("VR mode not supported on this device!");
12248        }
12249
12250        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12251
12252        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12253                VrManagerInternal.NO_ERROR;
12254    }
12255
12256    public boolean isTopActivityImmersive() {
12257        enforceNotIsolatedCaller("startActivity");
12258        synchronized (this) {
12259            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12260            return (r != null) ? r.immersive : false;
12261        }
12262    }
12263
12264    @Override
12265    public boolean isTopOfTask(IBinder token) {
12266        synchronized (this) {
12267            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12268            if (r == null) {
12269                throw new IllegalArgumentException();
12270            }
12271            return r.task.getTopActivity() == r;
12272        }
12273    }
12274
12275    public final void enterSafeMode() {
12276        synchronized(this) {
12277            // It only makes sense to do this before the system is ready
12278            // and started launching other packages.
12279            if (!mSystemReady) {
12280                try {
12281                    AppGlobals.getPackageManager().enterSafeMode();
12282                } catch (RemoteException e) {
12283                }
12284            }
12285
12286            mSafeMode = true;
12287        }
12288    }
12289
12290    public final void showSafeModeOverlay() {
12291        View v = LayoutInflater.from(mContext).inflate(
12292                com.android.internal.R.layout.safe_mode, null);
12293        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12294        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12295        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12296        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12297        lp.gravity = Gravity.BOTTOM | Gravity.START;
12298        lp.format = v.getBackground().getOpacity();
12299        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12300                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12301        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12302        ((WindowManager)mContext.getSystemService(
12303                Context.WINDOW_SERVICE)).addView(v, lp);
12304    }
12305
12306    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12307        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12308            return;
12309        }
12310        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12311        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12312        synchronized (stats) {
12313            if (mBatteryStatsService.isOnBattery()) {
12314                mBatteryStatsService.enforceCallingPermission();
12315                int MY_UID = Binder.getCallingUid();
12316                final int uid;
12317                if (sender == null) {
12318                    uid = sourceUid;
12319                } else {
12320                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12321                }
12322                BatteryStatsImpl.Uid.Pkg pkg =
12323                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12324                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12325                pkg.noteWakeupAlarmLocked(tag);
12326            }
12327        }
12328    }
12329
12330    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12331        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12332            return;
12333        }
12334        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12335        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12336        synchronized (stats) {
12337            mBatteryStatsService.enforceCallingPermission();
12338            int MY_UID = Binder.getCallingUid();
12339            final int uid;
12340            if (sender == null) {
12341                uid = sourceUid;
12342            } else {
12343                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12344            }
12345            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12346        }
12347    }
12348
12349    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12350        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12351            return;
12352        }
12353        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12354        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12355        synchronized (stats) {
12356            mBatteryStatsService.enforceCallingPermission();
12357            int MY_UID = Binder.getCallingUid();
12358            final int uid;
12359            if (sender == null) {
12360                uid = sourceUid;
12361            } else {
12362                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12363            }
12364            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12365        }
12366    }
12367
12368    public boolean killPids(int[] pids, String pReason, boolean secure) {
12369        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12370            throw new SecurityException("killPids only available to the system");
12371        }
12372        String reason = (pReason == null) ? "Unknown" : pReason;
12373        // XXX Note: don't acquire main activity lock here, because the window
12374        // manager calls in with its locks held.
12375
12376        boolean killed = false;
12377        synchronized (mPidsSelfLocked) {
12378            int worstType = 0;
12379            for (int i=0; i<pids.length; i++) {
12380                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12381                if (proc != null) {
12382                    int type = proc.setAdj;
12383                    if (type > worstType) {
12384                        worstType = type;
12385                    }
12386                }
12387            }
12388
12389            // If the worst oom_adj is somewhere in the cached proc LRU range,
12390            // then constrain it so we will kill all cached procs.
12391            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12392                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12393                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12394            }
12395
12396            // If this is not a secure call, don't let it kill processes that
12397            // are important.
12398            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12399                worstType = ProcessList.SERVICE_ADJ;
12400            }
12401
12402            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12403            for (int i=0; i<pids.length; i++) {
12404                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12405                if (proc == null) {
12406                    continue;
12407                }
12408                int adj = proc.setAdj;
12409                if (adj >= worstType && !proc.killedByAm) {
12410                    proc.kill(reason, true);
12411                    killed = true;
12412                }
12413            }
12414        }
12415        return killed;
12416    }
12417
12418    @Override
12419    public void killUid(int appId, int userId, String reason) {
12420        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12421        synchronized (this) {
12422            final long identity = Binder.clearCallingIdentity();
12423            try {
12424                killPackageProcessesLocked(null, appId, userId,
12425                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12426                        reason != null ? reason : "kill uid");
12427            } finally {
12428                Binder.restoreCallingIdentity(identity);
12429            }
12430        }
12431    }
12432
12433    @Override
12434    public boolean killProcessesBelowForeground(String reason) {
12435        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12436            throw new SecurityException("killProcessesBelowForeground() only available to system");
12437        }
12438
12439        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12440    }
12441
12442    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12443        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12444            throw new SecurityException("killProcessesBelowAdj() only available to system");
12445        }
12446
12447        boolean killed = false;
12448        synchronized (mPidsSelfLocked) {
12449            final int size = mPidsSelfLocked.size();
12450            for (int i = 0; i < size; i++) {
12451                final int pid = mPidsSelfLocked.keyAt(i);
12452                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12453                if (proc == null) continue;
12454
12455                final int adj = proc.setAdj;
12456                if (adj > belowAdj && !proc.killedByAm) {
12457                    proc.kill(reason, true);
12458                    killed = true;
12459                }
12460            }
12461        }
12462        return killed;
12463    }
12464
12465    @Override
12466    public void hang(final IBinder who, boolean allowRestart) {
12467        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12468                != PackageManager.PERMISSION_GRANTED) {
12469            throw new SecurityException("Requires permission "
12470                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12471        }
12472
12473        final IBinder.DeathRecipient death = new DeathRecipient() {
12474            @Override
12475            public void binderDied() {
12476                synchronized (this) {
12477                    notifyAll();
12478                }
12479            }
12480        };
12481
12482        try {
12483            who.linkToDeath(death, 0);
12484        } catch (RemoteException e) {
12485            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12486            return;
12487        }
12488
12489        synchronized (this) {
12490            Watchdog.getInstance().setAllowRestart(allowRestart);
12491            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12492            synchronized (death) {
12493                while (who.isBinderAlive()) {
12494                    try {
12495                        death.wait();
12496                    } catch (InterruptedException e) {
12497                    }
12498                }
12499            }
12500            Watchdog.getInstance().setAllowRestart(true);
12501        }
12502    }
12503
12504    @Override
12505    public void restart() {
12506        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12507                != PackageManager.PERMISSION_GRANTED) {
12508            throw new SecurityException("Requires permission "
12509                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12510        }
12511
12512        Log.i(TAG, "Sending shutdown broadcast...");
12513
12514        BroadcastReceiver br = new BroadcastReceiver() {
12515            @Override public void onReceive(Context context, Intent intent) {
12516                // Now the broadcast is done, finish up the low-level shutdown.
12517                Log.i(TAG, "Shutting down activity manager...");
12518                shutdown(10000);
12519                Log.i(TAG, "Shutdown complete, restarting!");
12520                Process.killProcess(Process.myPid());
12521                System.exit(10);
12522            }
12523        };
12524
12525        // First send the high-level shut down broadcast.
12526        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12527        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12528        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12529        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12530        mContext.sendOrderedBroadcastAsUser(intent,
12531                UserHandle.ALL, null, br, mHandler, 0, null, null);
12532        */
12533        br.onReceive(mContext, intent);
12534    }
12535
12536    private long getLowRamTimeSinceIdle(long now) {
12537        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12538    }
12539
12540    @Override
12541    public void performIdleMaintenance() {
12542        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12543                != PackageManager.PERMISSION_GRANTED) {
12544            throw new SecurityException("Requires permission "
12545                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12546        }
12547
12548        synchronized (this) {
12549            final long now = SystemClock.uptimeMillis();
12550            final long timeSinceLastIdle = now - mLastIdleTime;
12551            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12552            mLastIdleTime = now;
12553            mLowRamTimeSinceLastIdle = 0;
12554            if (mLowRamStartTime != 0) {
12555                mLowRamStartTime = now;
12556            }
12557
12558            StringBuilder sb = new StringBuilder(128);
12559            sb.append("Idle maintenance over ");
12560            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12561            sb.append(" low RAM for ");
12562            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12563            Slog.i(TAG, sb.toString());
12564
12565            // If at least 1/3 of our time since the last idle period has been spent
12566            // with RAM low, then we want to kill processes.
12567            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12568
12569            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12570                ProcessRecord proc = mLruProcesses.get(i);
12571                if (proc.notCachedSinceIdle) {
12572                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12573                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12574                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12575                        if (doKilling && proc.initialIdlePss != 0
12576                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12577                            sb = new StringBuilder(128);
12578                            sb.append("Kill");
12579                            sb.append(proc.processName);
12580                            sb.append(" in idle maint: pss=");
12581                            sb.append(proc.lastPss);
12582                            sb.append(", swapPss=");
12583                            sb.append(proc.lastSwapPss);
12584                            sb.append(", initialPss=");
12585                            sb.append(proc.initialIdlePss);
12586                            sb.append(", period=");
12587                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12588                            sb.append(", lowRamPeriod=");
12589                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12590                            Slog.wtfQuiet(TAG, sb.toString());
12591                            proc.kill("idle maint (pss " + proc.lastPss
12592                                    + " from " + proc.initialIdlePss + ")", true);
12593                        }
12594                    }
12595                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12596                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12597                    proc.notCachedSinceIdle = true;
12598                    proc.initialIdlePss = 0;
12599                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12600                            mTestPssMode, isSleeping(), now);
12601                }
12602            }
12603
12604            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12605            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12606        }
12607    }
12608
12609    private void retrieveSettings() {
12610        final ContentResolver resolver = mContext.getContentResolver();
12611        final boolean freeformWindowManagement =
12612                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12613                        || Settings.Global.getInt(
12614                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12615        final boolean supportsPictureInPicture =
12616                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12617
12618        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12619        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12620        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12621        final boolean alwaysFinishActivities =
12622                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12623        final boolean lenientBackgroundCheck =
12624                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12625        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12626        final boolean forceResizable = Settings.Global.getInt(
12627                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12628        // Transfer any global setting for forcing RTL layout, into a System Property
12629        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12630
12631        final Configuration configuration = new Configuration();
12632        Settings.System.getConfiguration(resolver, configuration);
12633        if (forceRtl) {
12634            // This will take care of setting the correct layout direction flags
12635            configuration.setLayoutDirection(configuration.locale);
12636        }
12637
12638        synchronized (this) {
12639            mDebugApp = mOrigDebugApp = debugApp;
12640            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12641            mAlwaysFinishActivities = alwaysFinishActivities;
12642            mLenientBackgroundCheck = lenientBackgroundCheck;
12643            mForceResizableActivities = forceResizable;
12644            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12645            if (supportsMultiWindow || forceResizable) {
12646                mSupportsMultiWindow = true;
12647                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12648                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12649            } else {
12650                mSupportsMultiWindow = false;
12651                mSupportsFreeformWindowManagement = false;
12652                mSupportsPictureInPicture = false;
12653            }
12654            // This happens before any activities are started, so we can
12655            // change mConfiguration in-place.
12656            updateConfigurationLocked(configuration, null, true);
12657            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12658                    "Initial config: " + mConfiguration);
12659
12660            // Load resources only after the current configuration has been set.
12661            final Resources res = mContext.getResources();
12662            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12663            mThumbnailWidth = res.getDimensionPixelSize(
12664                    com.android.internal.R.dimen.thumbnail_width);
12665            mThumbnailHeight = res.getDimensionPixelSize(
12666                    com.android.internal.R.dimen.thumbnail_height);
12667            mFullscreenThumbnailScale = res.getFraction(
12668                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12669            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12670                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12671            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12672                    com.android.internal.R.string.config_appsNotReportingCrashes));
12673        }
12674    }
12675
12676    public boolean testIsSystemReady() {
12677        // no need to synchronize(this) just to read & return the value
12678        return mSystemReady;
12679    }
12680
12681    public void systemReady(final Runnable goingCallback) {
12682        synchronized(this) {
12683            if (mSystemReady) {
12684                // If we're done calling all the receivers, run the next "boot phase" passed in
12685                // by the SystemServer
12686                if (goingCallback != null) {
12687                    goingCallback.run();
12688                }
12689                return;
12690            }
12691
12692            mLocalDeviceIdleController
12693                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12694
12695            // Make sure we have the current profile info, since it is needed for security checks.
12696            mUserController.onSystemReady();
12697            mRecentTasks.onSystemReadyLocked();
12698            mAppOpsService.systemReady();
12699            mSystemReady = true;
12700        }
12701
12702        ArrayList<ProcessRecord> procsToKill = null;
12703        synchronized(mPidsSelfLocked) {
12704            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12705                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12706                if (!isAllowedWhileBooting(proc.info)){
12707                    if (procsToKill == null) {
12708                        procsToKill = new ArrayList<ProcessRecord>();
12709                    }
12710                    procsToKill.add(proc);
12711                }
12712            }
12713        }
12714
12715        synchronized(this) {
12716            if (procsToKill != null) {
12717                for (int i=procsToKill.size()-1; i>=0; i--) {
12718                    ProcessRecord proc = procsToKill.get(i);
12719                    Slog.i(TAG, "Removing system update proc: " + proc);
12720                    removeProcessLocked(proc, true, false, "system update done");
12721                }
12722            }
12723
12724            // Now that we have cleaned up any update processes, we
12725            // are ready to start launching real processes and know that
12726            // we won't trample on them any more.
12727            mProcessesReady = true;
12728        }
12729
12730        Slog.i(TAG, "System now ready");
12731        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12732            SystemClock.uptimeMillis());
12733
12734        synchronized(this) {
12735            // Make sure we have no pre-ready processes sitting around.
12736
12737            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12738                ResolveInfo ri = mContext.getPackageManager()
12739                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12740                                STOCK_PM_FLAGS);
12741                CharSequence errorMsg = null;
12742                if (ri != null) {
12743                    ActivityInfo ai = ri.activityInfo;
12744                    ApplicationInfo app = ai.applicationInfo;
12745                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12746                        mTopAction = Intent.ACTION_FACTORY_TEST;
12747                        mTopData = null;
12748                        mTopComponent = new ComponentName(app.packageName,
12749                                ai.name);
12750                    } else {
12751                        errorMsg = mContext.getResources().getText(
12752                                com.android.internal.R.string.factorytest_not_system);
12753                    }
12754                } else {
12755                    errorMsg = mContext.getResources().getText(
12756                            com.android.internal.R.string.factorytest_no_action);
12757                }
12758                if (errorMsg != null) {
12759                    mTopAction = null;
12760                    mTopData = null;
12761                    mTopComponent = null;
12762                    Message msg = Message.obtain();
12763                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12764                    msg.getData().putCharSequence("msg", errorMsg);
12765                    mUiHandler.sendMessage(msg);
12766                }
12767            }
12768        }
12769
12770        retrieveSettings();
12771        final int currentUserId;
12772        synchronized (this) {
12773            currentUserId = mUserController.getCurrentUserIdLocked();
12774            readGrantedUriPermissionsLocked();
12775        }
12776
12777        if (goingCallback != null) goingCallback.run();
12778
12779        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12780                Integer.toString(currentUserId), currentUserId);
12781        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12782                Integer.toString(currentUserId), currentUserId);
12783        mSystemServiceManager.startUser(currentUserId);
12784
12785        synchronized (this) {
12786            // Only start up encryption-aware persistent apps; once user is
12787            // unlocked we'll come back around and start unaware apps
12788            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12789
12790            // Start up initial activity.
12791            mBooting = true;
12792            // Enable home activity for system user, so that the system can always boot
12793            if (UserManager.isSplitSystemUser()) {
12794                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12795                try {
12796                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12797                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12798                            UserHandle.USER_SYSTEM);
12799                } catch (RemoteException e) {
12800                    throw e.rethrowAsRuntimeException();
12801                }
12802            }
12803            startHomeActivityLocked(currentUserId, "systemReady");
12804
12805            try {
12806                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12807                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12808                            + " data partition or your device will be unstable.");
12809                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12810                }
12811            } catch (RemoteException e) {
12812            }
12813
12814            if (!Build.isBuildConsistent()) {
12815                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12816                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12817            }
12818
12819            long ident = Binder.clearCallingIdentity();
12820            try {
12821                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12822                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12823                        | Intent.FLAG_RECEIVER_FOREGROUND);
12824                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12825                broadcastIntentLocked(null, null, intent,
12826                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12827                        null, false, false, MY_PID, Process.SYSTEM_UID,
12828                        currentUserId);
12829                intent = new Intent(Intent.ACTION_USER_STARTING);
12830                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12831                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12832                broadcastIntentLocked(null, null, intent,
12833                        null, new IIntentReceiver.Stub() {
12834                            @Override
12835                            public void performReceive(Intent intent, int resultCode, String data,
12836                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12837                                    throws RemoteException {
12838                            }
12839                        }, 0, null, null,
12840                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12841                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12842            } catch (Throwable t) {
12843                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12844            } finally {
12845                Binder.restoreCallingIdentity(ident);
12846            }
12847            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12848            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12849        }
12850    }
12851
12852    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12853        synchronized (this) {
12854            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12855        }
12856    }
12857
12858    void skipCurrentReceiverLocked(ProcessRecord app) {
12859        for (BroadcastQueue queue : mBroadcastQueues) {
12860            queue.skipCurrentReceiverLocked(app);
12861        }
12862    }
12863
12864    /**
12865     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12866     * The application process will exit immediately after this call returns.
12867     * @param app object of the crashing app, null for the system server
12868     * @param crashInfo describing the exception
12869     */
12870    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12871        ProcessRecord r = findAppProcess(app, "Crash");
12872        final String processName = app == null ? "system_server"
12873                : (r == null ? "unknown" : r.processName);
12874
12875        handleApplicationCrashInner("crash", r, processName, crashInfo);
12876    }
12877
12878    /* Native crash reporting uses this inner version because it needs to be somewhat
12879     * decoupled from the AM-managed cleanup lifecycle
12880     */
12881    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12882            ApplicationErrorReport.CrashInfo crashInfo) {
12883        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12884                UserHandle.getUserId(Binder.getCallingUid()), processName,
12885                r == null ? -1 : r.info.flags,
12886                crashInfo.exceptionClassName,
12887                crashInfo.exceptionMessage,
12888                crashInfo.throwFileName,
12889                crashInfo.throwLineNumber);
12890
12891        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12892
12893        mAppErrors.crashApplication(r, crashInfo);
12894    }
12895
12896    public void handleApplicationStrictModeViolation(
12897            IBinder app,
12898            int violationMask,
12899            StrictMode.ViolationInfo info) {
12900        ProcessRecord r = findAppProcess(app, "StrictMode");
12901        if (r == null) {
12902            return;
12903        }
12904
12905        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12906            Integer stackFingerprint = info.hashCode();
12907            boolean logIt = true;
12908            synchronized (mAlreadyLoggedViolatedStacks) {
12909                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12910                    logIt = false;
12911                    // TODO: sub-sample into EventLog for these, with
12912                    // the info.durationMillis?  Then we'd get
12913                    // the relative pain numbers, without logging all
12914                    // the stack traces repeatedly.  We'd want to do
12915                    // likewise in the client code, which also does
12916                    // dup suppression, before the Binder call.
12917                } else {
12918                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12919                        mAlreadyLoggedViolatedStacks.clear();
12920                    }
12921                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12922                }
12923            }
12924            if (logIt) {
12925                logStrictModeViolationToDropBox(r, info);
12926            }
12927        }
12928
12929        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12930            AppErrorResult result = new AppErrorResult();
12931            synchronized (this) {
12932                final long origId = Binder.clearCallingIdentity();
12933
12934                Message msg = Message.obtain();
12935                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12936                HashMap<String, Object> data = new HashMap<String, Object>();
12937                data.put("result", result);
12938                data.put("app", r);
12939                data.put("violationMask", violationMask);
12940                data.put("info", info);
12941                msg.obj = data;
12942                mUiHandler.sendMessage(msg);
12943
12944                Binder.restoreCallingIdentity(origId);
12945            }
12946            int res = result.get();
12947            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12948        }
12949    }
12950
12951    // Depending on the policy in effect, there could be a bunch of
12952    // these in quick succession so we try to batch these together to
12953    // minimize disk writes, number of dropbox entries, and maximize
12954    // compression, by having more fewer, larger records.
12955    private void logStrictModeViolationToDropBox(
12956            ProcessRecord process,
12957            StrictMode.ViolationInfo info) {
12958        if (info == null) {
12959            return;
12960        }
12961        final boolean isSystemApp = process == null ||
12962                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12963                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12964        final String processName = process == null ? "unknown" : process.processName;
12965        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12966        final DropBoxManager dbox = (DropBoxManager)
12967                mContext.getSystemService(Context.DROPBOX_SERVICE);
12968
12969        // Exit early if the dropbox isn't configured to accept this report type.
12970        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12971
12972        boolean bufferWasEmpty;
12973        boolean needsFlush;
12974        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12975        synchronized (sb) {
12976            bufferWasEmpty = sb.length() == 0;
12977            appendDropBoxProcessHeaders(process, processName, sb);
12978            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12979            sb.append("System-App: ").append(isSystemApp).append("\n");
12980            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12981            if (info.violationNumThisLoop != 0) {
12982                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12983            }
12984            if (info.numAnimationsRunning != 0) {
12985                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12986            }
12987            if (info.broadcastIntentAction != null) {
12988                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12989            }
12990            if (info.durationMillis != -1) {
12991                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12992            }
12993            if (info.numInstances != -1) {
12994                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12995            }
12996            if (info.tags != null) {
12997                for (String tag : info.tags) {
12998                    sb.append("Span-Tag: ").append(tag).append("\n");
12999                }
13000            }
13001            sb.append("\n");
13002            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13003                sb.append(info.crashInfo.stackTrace);
13004                sb.append("\n");
13005            }
13006            if (info.message != null) {
13007                sb.append(info.message);
13008                sb.append("\n");
13009            }
13010
13011            // Only buffer up to ~64k.  Various logging bits truncate
13012            // things at 128k.
13013            needsFlush = (sb.length() > 64 * 1024);
13014        }
13015
13016        // Flush immediately if the buffer's grown too large, or this
13017        // is a non-system app.  Non-system apps are isolated with a
13018        // different tag & policy and not batched.
13019        //
13020        // Batching is useful during internal testing with
13021        // StrictMode settings turned up high.  Without batching,
13022        // thousands of separate files could be created on boot.
13023        if (!isSystemApp || needsFlush) {
13024            new Thread("Error dump: " + dropboxTag) {
13025                @Override
13026                public void run() {
13027                    String report;
13028                    synchronized (sb) {
13029                        report = sb.toString();
13030                        sb.delete(0, sb.length());
13031                        sb.trimToSize();
13032                    }
13033                    if (report.length() != 0) {
13034                        dbox.addText(dropboxTag, report);
13035                    }
13036                }
13037            }.start();
13038            return;
13039        }
13040
13041        // System app batching:
13042        if (!bufferWasEmpty) {
13043            // An existing dropbox-writing thread is outstanding, so
13044            // we don't need to start it up.  The existing thread will
13045            // catch the buffer appends we just did.
13046            return;
13047        }
13048
13049        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13050        // (After this point, we shouldn't access AMS internal data structures.)
13051        new Thread("Error dump: " + dropboxTag) {
13052            @Override
13053            public void run() {
13054                // 5 second sleep to let stacks arrive and be batched together
13055                try {
13056                    Thread.sleep(5000);  // 5 seconds
13057                } catch (InterruptedException e) {}
13058
13059                String errorReport;
13060                synchronized (mStrictModeBuffer) {
13061                    errorReport = mStrictModeBuffer.toString();
13062                    if (errorReport.length() == 0) {
13063                        return;
13064                    }
13065                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13066                    mStrictModeBuffer.trimToSize();
13067                }
13068                dbox.addText(dropboxTag, errorReport);
13069            }
13070        }.start();
13071    }
13072
13073    /**
13074     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13075     * @param app object of the crashing app, null for the system server
13076     * @param tag reported by the caller
13077     * @param system whether this wtf is coming from the system
13078     * @param crashInfo describing the context of the error
13079     * @return true if the process should exit immediately (WTF is fatal)
13080     */
13081    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13082            final ApplicationErrorReport.CrashInfo crashInfo) {
13083        final int callingUid = Binder.getCallingUid();
13084        final int callingPid = Binder.getCallingPid();
13085
13086        if (system) {
13087            // If this is coming from the system, we could very well have low-level
13088            // system locks held, so we want to do this all asynchronously.  And we
13089            // never want this to become fatal, so there is that too.
13090            mHandler.post(new Runnable() {
13091                @Override public void run() {
13092                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13093                }
13094            });
13095            return false;
13096        }
13097
13098        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13099                crashInfo);
13100
13101        if (r != null && r.pid != Process.myPid() &&
13102                Settings.Global.getInt(mContext.getContentResolver(),
13103                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13104            mAppErrors.crashApplication(r, crashInfo);
13105            return true;
13106        } else {
13107            return false;
13108        }
13109    }
13110
13111    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13112            final ApplicationErrorReport.CrashInfo crashInfo) {
13113        final ProcessRecord r = findAppProcess(app, "WTF");
13114        final String processName = app == null ? "system_server"
13115                : (r == null ? "unknown" : r.processName);
13116
13117        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13118                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13119
13120        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13121
13122        return r;
13123    }
13124
13125    /**
13126     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13127     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13128     */
13129    private ProcessRecord findAppProcess(IBinder app, String reason) {
13130        if (app == null) {
13131            return null;
13132        }
13133
13134        synchronized (this) {
13135            final int NP = mProcessNames.getMap().size();
13136            for (int ip=0; ip<NP; ip++) {
13137                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13138                final int NA = apps.size();
13139                for (int ia=0; ia<NA; ia++) {
13140                    ProcessRecord p = apps.valueAt(ia);
13141                    if (p.thread != null && p.thread.asBinder() == app) {
13142                        return p;
13143                    }
13144                }
13145            }
13146
13147            Slog.w(TAG, "Can't find mystery application for " + reason
13148                    + " from pid=" + Binder.getCallingPid()
13149                    + " uid=" + Binder.getCallingUid() + ": " + app);
13150            return null;
13151        }
13152    }
13153
13154    /**
13155     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13156     * to append various headers to the dropbox log text.
13157     */
13158    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13159            StringBuilder sb) {
13160        // Watchdog thread ends up invoking this function (with
13161        // a null ProcessRecord) to add the stack file to dropbox.
13162        // Do not acquire a lock on this (am) in such cases, as it
13163        // could cause a potential deadlock, if and when watchdog
13164        // is invoked due to unavailability of lock on am and it
13165        // would prevent watchdog from killing system_server.
13166        if (process == null) {
13167            sb.append("Process: ").append(processName).append("\n");
13168            return;
13169        }
13170        // Note: ProcessRecord 'process' is guarded by the service
13171        // instance.  (notably process.pkgList, which could otherwise change
13172        // concurrently during execution of this method)
13173        synchronized (this) {
13174            sb.append("Process: ").append(processName).append("\n");
13175            int flags = process.info.flags;
13176            IPackageManager pm = AppGlobals.getPackageManager();
13177            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13178            for (int ip=0; ip<process.pkgList.size(); ip++) {
13179                String pkg = process.pkgList.keyAt(ip);
13180                sb.append("Package: ").append(pkg);
13181                try {
13182                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13183                    if (pi != null) {
13184                        sb.append(" v").append(pi.versionCode);
13185                        if (pi.versionName != null) {
13186                            sb.append(" (").append(pi.versionName).append(")");
13187                        }
13188                    }
13189                } catch (RemoteException e) {
13190                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13191                }
13192                sb.append("\n");
13193            }
13194        }
13195    }
13196
13197    private static String processClass(ProcessRecord process) {
13198        if (process == null || process.pid == MY_PID) {
13199            return "system_server";
13200        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13201            return "system_app";
13202        } else {
13203            return "data_app";
13204        }
13205    }
13206
13207    private volatile long mWtfClusterStart;
13208    private volatile int mWtfClusterCount;
13209
13210    /**
13211     * Write a description of an error (crash, WTF, ANR) to the drop box.
13212     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13213     * @param process which caused the error, null means the system server
13214     * @param activity which triggered the error, null if unknown
13215     * @param parent activity related to the error, null if unknown
13216     * @param subject line related to the error, null if absent
13217     * @param report in long form describing the error, null if absent
13218     * @param logFile to include in the report, null if none
13219     * @param crashInfo giving an application stack trace, null if absent
13220     */
13221    public void addErrorToDropBox(String eventType,
13222            ProcessRecord process, String processName, ActivityRecord activity,
13223            ActivityRecord parent, String subject,
13224            final String report, final File logFile,
13225            final ApplicationErrorReport.CrashInfo crashInfo) {
13226        // NOTE -- this must never acquire the ActivityManagerService lock,
13227        // otherwise the watchdog may be prevented from resetting the system.
13228
13229        final String dropboxTag = processClass(process) + "_" + eventType;
13230        final DropBoxManager dbox = (DropBoxManager)
13231                mContext.getSystemService(Context.DROPBOX_SERVICE);
13232
13233        // Exit early if the dropbox isn't configured to accept this report type.
13234        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13235
13236        // Rate-limit how often we're willing to do the heavy lifting below to
13237        // collect and record logs; currently 5 logs per 10 second period.
13238        final long now = SystemClock.elapsedRealtime();
13239        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13240            mWtfClusterStart = now;
13241            mWtfClusterCount = 1;
13242        } else {
13243            if (mWtfClusterCount++ >= 5) return;
13244        }
13245
13246        final StringBuilder sb = new StringBuilder(1024);
13247        appendDropBoxProcessHeaders(process, processName, sb);
13248        if (process != null) {
13249            sb.append("Foreground: ")
13250                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13251                    .append("\n");
13252        }
13253        if (activity != null) {
13254            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13255        }
13256        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13257            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13258        }
13259        if (parent != null && parent != activity) {
13260            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13261        }
13262        if (subject != null) {
13263            sb.append("Subject: ").append(subject).append("\n");
13264        }
13265        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13266        if (Debug.isDebuggerConnected()) {
13267            sb.append("Debugger: Connected\n");
13268        }
13269        sb.append("\n");
13270
13271        // Do the rest in a worker thread to avoid blocking the caller on I/O
13272        // (After this point, we shouldn't access AMS internal data structures.)
13273        Thread worker = new Thread("Error dump: " + dropboxTag) {
13274            @Override
13275            public void run() {
13276                if (report != null) {
13277                    sb.append(report);
13278                }
13279                if (logFile != null) {
13280                    try {
13281                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13282                                    "\n\n[[TRUNCATED]]"));
13283                    } catch (IOException e) {
13284                        Slog.e(TAG, "Error reading " + logFile, e);
13285                    }
13286                }
13287                if (crashInfo != null && crashInfo.stackTrace != null) {
13288                    sb.append(crashInfo.stackTrace);
13289                }
13290
13291                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13292                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13293                if (lines > 0) {
13294                    sb.append("\n");
13295
13296                    // Merge several logcat streams, and take the last N lines
13297                    InputStreamReader input = null;
13298                    try {
13299                        java.lang.Process logcat = new ProcessBuilder(
13300                                "/system/bin/timeout", "-k", "15s", "10s",
13301                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13302                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13303                                        .redirectErrorStream(true).start();
13304
13305                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13306                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13307                        input = new InputStreamReader(logcat.getInputStream());
13308
13309                        int num;
13310                        char[] buf = new char[8192];
13311                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13312                    } catch (IOException e) {
13313                        Slog.e(TAG, "Error running logcat", e);
13314                    } finally {
13315                        if (input != null) try { input.close(); } catch (IOException e) {}
13316                    }
13317                }
13318
13319                dbox.addText(dropboxTag, sb.toString());
13320            }
13321        };
13322
13323        if (process == null) {
13324            // If process is null, we are being called from some internal code
13325            // and may be about to die -- run this synchronously.
13326            worker.run();
13327        } else {
13328            worker.start();
13329        }
13330    }
13331
13332    @Override
13333    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13334        enforceNotIsolatedCaller("getProcessesInErrorState");
13335        // assume our apps are happy - lazy create the list
13336        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13337
13338        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13339                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13340        int userId = UserHandle.getUserId(Binder.getCallingUid());
13341
13342        synchronized (this) {
13343
13344            // iterate across all processes
13345            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13346                ProcessRecord app = mLruProcesses.get(i);
13347                if (!allUsers && app.userId != userId) {
13348                    continue;
13349                }
13350                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13351                    // This one's in trouble, so we'll generate a report for it
13352                    // crashes are higher priority (in case there's a crash *and* an anr)
13353                    ActivityManager.ProcessErrorStateInfo report = null;
13354                    if (app.crashing) {
13355                        report = app.crashingReport;
13356                    } else if (app.notResponding) {
13357                        report = app.notRespondingReport;
13358                    }
13359
13360                    if (report != null) {
13361                        if (errList == null) {
13362                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13363                        }
13364                        errList.add(report);
13365                    } else {
13366                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13367                                " crashing = " + app.crashing +
13368                                " notResponding = " + app.notResponding);
13369                    }
13370                }
13371            }
13372        }
13373
13374        return errList;
13375    }
13376
13377    static int procStateToImportance(int procState, int memAdj,
13378            ActivityManager.RunningAppProcessInfo currApp) {
13379        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13380        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13381            currApp.lru = memAdj;
13382        } else {
13383            currApp.lru = 0;
13384        }
13385        return imp;
13386    }
13387
13388    private void fillInProcMemInfo(ProcessRecord app,
13389            ActivityManager.RunningAppProcessInfo outInfo) {
13390        outInfo.pid = app.pid;
13391        outInfo.uid = app.info.uid;
13392        if (mHeavyWeightProcess == app) {
13393            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13394        }
13395        if (app.persistent) {
13396            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13397        }
13398        if (app.activities.size() > 0) {
13399            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13400        }
13401        outInfo.lastTrimLevel = app.trimMemoryLevel;
13402        int adj = app.curAdj;
13403        int procState = app.curProcState;
13404        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13405        outInfo.importanceReasonCode = app.adjTypeCode;
13406        outInfo.processState = app.curProcState;
13407    }
13408
13409    @Override
13410    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13411        enforceNotIsolatedCaller("getRunningAppProcesses");
13412
13413        final int callingUid = Binder.getCallingUid();
13414
13415        // Lazy instantiation of list
13416        List<ActivityManager.RunningAppProcessInfo> runList = null;
13417        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13418                callingUid) == PackageManager.PERMISSION_GRANTED;
13419        final int userId = UserHandle.getUserId(callingUid);
13420        final boolean allUids = isGetTasksAllowed(
13421                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13422
13423        synchronized (this) {
13424            // Iterate across all processes
13425            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13426                ProcessRecord app = mLruProcesses.get(i);
13427                if ((!allUsers && app.userId != userId)
13428                        || (!allUids && app.uid != callingUid)) {
13429                    continue;
13430                }
13431                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13432                    // Generate process state info for running application
13433                    ActivityManager.RunningAppProcessInfo currApp =
13434                        new ActivityManager.RunningAppProcessInfo(app.processName,
13435                                app.pid, app.getPackageList());
13436                    fillInProcMemInfo(app, currApp);
13437                    if (app.adjSource instanceof ProcessRecord) {
13438                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13439                        currApp.importanceReasonImportance =
13440                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13441                                        app.adjSourceProcState);
13442                    } else if (app.adjSource instanceof ActivityRecord) {
13443                        ActivityRecord r = (ActivityRecord)app.adjSource;
13444                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13445                    }
13446                    if (app.adjTarget instanceof ComponentName) {
13447                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13448                    }
13449                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13450                    //        + " lru=" + currApp.lru);
13451                    if (runList == null) {
13452                        runList = new ArrayList<>();
13453                    }
13454                    runList.add(currApp);
13455                }
13456            }
13457        }
13458        return runList;
13459    }
13460
13461    @Override
13462    public List<ApplicationInfo> getRunningExternalApplications() {
13463        enforceNotIsolatedCaller("getRunningExternalApplications");
13464        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13465        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13466        if (runningApps != null && runningApps.size() > 0) {
13467            Set<String> extList = new HashSet<String>();
13468            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13469                if (app.pkgList != null) {
13470                    for (String pkg : app.pkgList) {
13471                        extList.add(pkg);
13472                    }
13473                }
13474            }
13475            IPackageManager pm = AppGlobals.getPackageManager();
13476            for (String pkg : extList) {
13477                try {
13478                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13479                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13480                        retList.add(info);
13481                    }
13482                } catch (RemoteException e) {
13483                }
13484            }
13485        }
13486        return retList;
13487    }
13488
13489    @Override
13490    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13491        enforceNotIsolatedCaller("getMyMemoryState");
13492        synchronized (this) {
13493            ProcessRecord proc;
13494            synchronized (mPidsSelfLocked) {
13495                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13496            }
13497            fillInProcMemInfo(proc, outInfo);
13498        }
13499    }
13500
13501    @Override
13502    public int getMemoryTrimLevel() {
13503        enforceNotIsolatedCaller("getMyMemoryState");
13504        synchronized (this) {
13505            return mLastMemoryLevel;
13506        }
13507    }
13508
13509    @Override
13510    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13511            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13512        (new ActivityManagerShellCommand(this, false)).exec(
13513                this, in, out, err, args, resultReceiver);
13514    }
13515
13516    @Override
13517    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13518        if (checkCallingPermission(android.Manifest.permission.DUMP)
13519                != PackageManager.PERMISSION_GRANTED) {
13520            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13521                    + Binder.getCallingPid()
13522                    + ", uid=" + Binder.getCallingUid()
13523                    + " without permission "
13524                    + android.Manifest.permission.DUMP);
13525            return;
13526        }
13527
13528        boolean dumpAll = false;
13529        boolean dumpClient = false;
13530        String dumpPackage = null;
13531
13532        int opti = 0;
13533        while (opti < args.length) {
13534            String opt = args[opti];
13535            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13536                break;
13537            }
13538            opti++;
13539            if ("-a".equals(opt)) {
13540                dumpAll = true;
13541            } else if ("-c".equals(opt)) {
13542                dumpClient = true;
13543            } else if ("-p".equals(opt)) {
13544                if (opti < args.length) {
13545                    dumpPackage = args[opti];
13546                    opti++;
13547                } else {
13548                    pw.println("Error: -p option requires package argument");
13549                    return;
13550                }
13551                dumpClient = true;
13552            } else if ("-h".equals(opt)) {
13553                ActivityManagerShellCommand.dumpHelp(pw, true);
13554                return;
13555            } else {
13556                pw.println("Unknown argument: " + opt + "; use -h for help");
13557            }
13558        }
13559
13560        long origId = Binder.clearCallingIdentity();
13561        boolean more = false;
13562        // Is the caller requesting to dump a particular piece of data?
13563        if (opti < args.length) {
13564            String cmd = args[opti];
13565            opti++;
13566            if ("activities".equals(cmd) || "a".equals(cmd)) {
13567                synchronized (this) {
13568                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13569                }
13570            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13571                synchronized (this) {
13572                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13573                }
13574            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13575                String[] newArgs;
13576                String name;
13577                if (opti >= args.length) {
13578                    name = null;
13579                    newArgs = EMPTY_STRING_ARRAY;
13580                } else {
13581                    dumpPackage = args[opti];
13582                    opti++;
13583                    newArgs = new String[args.length - opti];
13584                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13585                            args.length - opti);
13586                }
13587                synchronized (this) {
13588                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13589                }
13590            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13591                String[] newArgs;
13592                String name;
13593                if (opti >= args.length) {
13594                    name = null;
13595                    newArgs = EMPTY_STRING_ARRAY;
13596                } else {
13597                    dumpPackage = args[opti];
13598                    opti++;
13599                    newArgs = new String[args.length - opti];
13600                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13601                            args.length - opti);
13602                }
13603                synchronized (this) {
13604                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13605                }
13606            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13607                String[] newArgs;
13608                String name;
13609                if (opti >= args.length) {
13610                    name = null;
13611                    newArgs = EMPTY_STRING_ARRAY;
13612                } else {
13613                    dumpPackage = args[opti];
13614                    opti++;
13615                    newArgs = new String[args.length - opti];
13616                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13617                            args.length - opti);
13618                }
13619                synchronized (this) {
13620                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13621                }
13622            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13623                synchronized (this) {
13624                    dumpOomLocked(fd, pw, args, opti, true);
13625                }
13626            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13627                synchronized (this) {
13628                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13629                }
13630            } else if ("provider".equals(cmd)) {
13631                String[] newArgs;
13632                String name;
13633                if (opti >= args.length) {
13634                    name = null;
13635                    newArgs = EMPTY_STRING_ARRAY;
13636                } else {
13637                    name = args[opti];
13638                    opti++;
13639                    newArgs = new String[args.length - opti];
13640                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13641                }
13642                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13643                    pw.println("No providers match: " + name);
13644                    pw.println("Use -h for help.");
13645                }
13646            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13647                synchronized (this) {
13648                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13649                }
13650            } else if ("service".equals(cmd)) {
13651                String[] newArgs;
13652                String name;
13653                if (opti >= args.length) {
13654                    name = null;
13655                    newArgs = EMPTY_STRING_ARRAY;
13656                } else {
13657                    name = args[opti];
13658                    opti++;
13659                    newArgs = new String[args.length - opti];
13660                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13661                            args.length - opti);
13662                }
13663                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13664                    pw.println("No services match: " + name);
13665                    pw.println("Use -h for help.");
13666                }
13667            } else if ("package".equals(cmd)) {
13668                String[] newArgs;
13669                if (opti >= args.length) {
13670                    pw.println("package: no package name specified");
13671                    pw.println("Use -h for help.");
13672                } else {
13673                    dumpPackage = args[opti];
13674                    opti++;
13675                    newArgs = new String[args.length - opti];
13676                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13677                            args.length - opti);
13678                    args = newArgs;
13679                    opti = 0;
13680                    more = true;
13681                }
13682            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13683                synchronized (this) {
13684                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13685                }
13686            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13687                synchronized (this) {
13688                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13689                }
13690            } else if ("locks".equals(cmd)) {
13691                LockGuard.dump(fd, pw, args);
13692            } else {
13693                // Dumping a single activity?
13694                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13695                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13696                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13697                    if (res < 0) {
13698                        pw.println("Bad activity command, or no activities match: " + cmd);
13699                        pw.println("Use -h for help.");
13700                    }
13701                }
13702            }
13703            if (!more) {
13704                Binder.restoreCallingIdentity(origId);
13705                return;
13706            }
13707        }
13708
13709        // No piece of data specified, dump everything.
13710        synchronized (this) {
13711            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13712            pw.println();
13713            if (dumpAll) {
13714                pw.println("-------------------------------------------------------------------------------");
13715            }
13716            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13717            pw.println();
13718            if (dumpAll) {
13719                pw.println("-------------------------------------------------------------------------------");
13720            }
13721            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13722            pw.println();
13723            if (dumpAll) {
13724                pw.println("-------------------------------------------------------------------------------");
13725            }
13726            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13727            pw.println();
13728            if (dumpAll) {
13729                pw.println("-------------------------------------------------------------------------------");
13730            }
13731            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13732            pw.println();
13733            if (dumpAll) {
13734                pw.println("-------------------------------------------------------------------------------");
13735            }
13736            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13737            pw.println();
13738            if (dumpAll) {
13739                pw.println("-------------------------------------------------------------------------------");
13740            }
13741            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13742            if (mAssociations.size() > 0) {
13743                pw.println();
13744                if (dumpAll) {
13745                    pw.println("-------------------------------------------------------------------------------");
13746                }
13747                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13748            }
13749            pw.println();
13750            if (dumpAll) {
13751                pw.println("-------------------------------------------------------------------------------");
13752            }
13753            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13754        }
13755        Binder.restoreCallingIdentity(origId);
13756    }
13757
13758    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13759            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13760        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13761
13762        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13763                dumpPackage);
13764        boolean needSep = printedAnything;
13765
13766        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13767                dumpPackage, needSep, "  mFocusedActivity: ");
13768        if (printed) {
13769            printedAnything = true;
13770            needSep = false;
13771        }
13772
13773        if (dumpPackage == null) {
13774            if (needSep) {
13775                pw.println();
13776            }
13777            needSep = true;
13778            printedAnything = true;
13779            mStackSupervisor.dump(pw, "  ");
13780        }
13781
13782        if (!printedAnything) {
13783            pw.println("  (nothing)");
13784        }
13785    }
13786
13787    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13788            int opti, boolean dumpAll, String dumpPackage) {
13789        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13790
13791        boolean printedAnything = false;
13792
13793        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13794            boolean printedHeader = false;
13795
13796            final int N = mRecentTasks.size();
13797            for (int i=0; i<N; i++) {
13798                TaskRecord tr = mRecentTasks.get(i);
13799                if (dumpPackage != null) {
13800                    if (tr.realActivity == null ||
13801                            !dumpPackage.equals(tr.realActivity)) {
13802                        continue;
13803                    }
13804                }
13805                if (!printedHeader) {
13806                    pw.println("  Recent tasks:");
13807                    printedHeader = true;
13808                    printedAnything = true;
13809                }
13810                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13811                        pw.println(tr);
13812                if (dumpAll) {
13813                    mRecentTasks.get(i).dump(pw, "    ");
13814                }
13815            }
13816        }
13817
13818        if (!printedAnything) {
13819            pw.println("  (nothing)");
13820        }
13821    }
13822
13823    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13824            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13825        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13826
13827        int dumpUid = 0;
13828        if (dumpPackage != null) {
13829            IPackageManager pm = AppGlobals.getPackageManager();
13830            try {
13831                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13832            } catch (RemoteException e) {
13833            }
13834        }
13835
13836        boolean printedAnything = false;
13837
13838        final long now = SystemClock.uptimeMillis();
13839
13840        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13841            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13842                    = mAssociations.valueAt(i1);
13843            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13844                SparseArray<ArrayMap<String, Association>> sourceUids
13845                        = targetComponents.valueAt(i2);
13846                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13847                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13848                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13849                        Association ass = sourceProcesses.valueAt(i4);
13850                        if (dumpPackage != null) {
13851                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13852                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13853                                continue;
13854                            }
13855                        }
13856                        printedAnything = true;
13857                        pw.print("  ");
13858                        pw.print(ass.mTargetProcess);
13859                        pw.print("/");
13860                        UserHandle.formatUid(pw, ass.mTargetUid);
13861                        pw.print(" <- ");
13862                        pw.print(ass.mSourceProcess);
13863                        pw.print("/");
13864                        UserHandle.formatUid(pw, ass.mSourceUid);
13865                        pw.println();
13866                        pw.print("    via ");
13867                        pw.print(ass.mTargetComponent.flattenToShortString());
13868                        pw.println();
13869                        pw.print("    ");
13870                        long dur = ass.mTime;
13871                        if (ass.mNesting > 0) {
13872                            dur += now - ass.mStartTime;
13873                        }
13874                        TimeUtils.formatDuration(dur, pw);
13875                        pw.print(" (");
13876                        pw.print(ass.mCount);
13877                        pw.print(" times)");
13878                        pw.print("  ");
13879                        for (int i=0; i<ass.mStateTimes.length; i++) {
13880                            long amt = ass.mStateTimes[i];
13881                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13882                                amt += now - ass.mLastStateUptime;
13883                            }
13884                            if (amt != 0) {
13885                                pw.print(" ");
13886                                pw.print(ProcessList.makeProcStateString(
13887                                            i + ActivityManager.MIN_PROCESS_STATE));
13888                                pw.print("=");
13889                                TimeUtils.formatDuration(amt, pw);
13890                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13891                                    pw.print("*");
13892                                }
13893                            }
13894                        }
13895                        pw.println();
13896                        if (ass.mNesting > 0) {
13897                            pw.print("    Currently active: ");
13898                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13899                            pw.println();
13900                        }
13901                    }
13902                }
13903            }
13904
13905        }
13906
13907        if (!printedAnything) {
13908            pw.println("  (nothing)");
13909        }
13910    }
13911
13912    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13913            String header, boolean needSep) {
13914        boolean printed = false;
13915        int whichAppId = -1;
13916        if (dumpPackage != null) {
13917            try {
13918                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13919                        dumpPackage, 0);
13920                whichAppId = UserHandle.getAppId(info.uid);
13921            } catch (NameNotFoundException e) {
13922                e.printStackTrace();
13923            }
13924        }
13925        for (int i=0; i<uids.size(); i++) {
13926            UidRecord uidRec = uids.valueAt(i);
13927            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13928                continue;
13929            }
13930            if (!printed) {
13931                printed = true;
13932                if (needSep) {
13933                    pw.println();
13934                }
13935                pw.print("  ");
13936                pw.println(header);
13937                needSep = true;
13938            }
13939            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13940            pw.print(": "); pw.println(uidRec);
13941        }
13942        return printed;
13943    }
13944
13945    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13946            int opti, boolean dumpAll, String dumpPackage) {
13947        boolean needSep = false;
13948        boolean printedAnything = false;
13949        int numPers = 0;
13950
13951        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13952
13953        if (dumpAll) {
13954            final int NP = mProcessNames.getMap().size();
13955            for (int ip=0; ip<NP; ip++) {
13956                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13957                final int NA = procs.size();
13958                for (int ia=0; ia<NA; ia++) {
13959                    ProcessRecord r = procs.valueAt(ia);
13960                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13961                        continue;
13962                    }
13963                    if (!needSep) {
13964                        pw.println("  All known processes:");
13965                        needSep = true;
13966                        printedAnything = true;
13967                    }
13968                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13969                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13970                        pw.print(" "); pw.println(r);
13971                    r.dump(pw, "    ");
13972                    if (r.persistent) {
13973                        numPers++;
13974                    }
13975                }
13976            }
13977        }
13978
13979        if (mIsolatedProcesses.size() > 0) {
13980            boolean printed = false;
13981            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13982                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13983                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13984                    continue;
13985                }
13986                if (!printed) {
13987                    if (needSep) {
13988                        pw.println();
13989                    }
13990                    pw.println("  Isolated process list (sorted by uid):");
13991                    printedAnything = true;
13992                    printed = true;
13993                    needSep = true;
13994                }
13995                pw.println(String.format("%sIsolated #%2d: %s",
13996                        "    ", i, r.toString()));
13997            }
13998        }
13999
14000        if (mActiveUids.size() > 0) {
14001            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14002                printedAnything = needSep = true;
14003            }
14004        }
14005        if (mValidateUids.size() > 0) {
14006            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14007                printedAnything = needSep = true;
14008            }
14009        }
14010
14011        if (mLruProcesses.size() > 0) {
14012            if (needSep) {
14013                pw.println();
14014            }
14015            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14016                    pw.print(" total, non-act at ");
14017                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14018                    pw.print(", non-svc at ");
14019                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14020                    pw.println("):");
14021            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14022            needSep = true;
14023            printedAnything = true;
14024        }
14025
14026        if (dumpAll || dumpPackage != null) {
14027            synchronized (mPidsSelfLocked) {
14028                boolean printed = false;
14029                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14030                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14031                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14032                        continue;
14033                    }
14034                    if (!printed) {
14035                        if (needSep) pw.println();
14036                        needSep = true;
14037                        pw.println("  PID mappings:");
14038                        printed = true;
14039                        printedAnything = true;
14040                    }
14041                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14042                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14043                }
14044            }
14045        }
14046
14047        if (mForegroundProcesses.size() > 0) {
14048            synchronized (mPidsSelfLocked) {
14049                boolean printed = false;
14050                for (int i=0; i<mForegroundProcesses.size(); i++) {
14051                    ProcessRecord r = mPidsSelfLocked.get(
14052                            mForegroundProcesses.valueAt(i).pid);
14053                    if (dumpPackage != null && (r == null
14054                            || !r.pkgList.containsKey(dumpPackage))) {
14055                        continue;
14056                    }
14057                    if (!printed) {
14058                        if (needSep) pw.println();
14059                        needSep = true;
14060                        pw.println("  Foreground Processes:");
14061                        printed = true;
14062                        printedAnything = true;
14063                    }
14064                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14065                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14066                }
14067            }
14068        }
14069
14070        if (mPersistentStartingProcesses.size() > 0) {
14071            if (needSep) pw.println();
14072            needSep = true;
14073            printedAnything = true;
14074            pw.println("  Persisent processes that are starting:");
14075            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14076                    "Starting Norm", "Restarting PERS", dumpPackage);
14077        }
14078
14079        if (mRemovedProcesses.size() > 0) {
14080            if (needSep) pw.println();
14081            needSep = true;
14082            printedAnything = true;
14083            pw.println("  Processes that are being removed:");
14084            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14085                    "Removed Norm", "Removed PERS", dumpPackage);
14086        }
14087
14088        if (mProcessesOnHold.size() > 0) {
14089            if (needSep) pw.println();
14090            needSep = true;
14091            printedAnything = true;
14092            pw.println("  Processes that are on old until the system is ready:");
14093            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14094                    "OnHold Norm", "OnHold PERS", dumpPackage);
14095        }
14096
14097        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14098
14099        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14100        if (needSep) {
14101            printedAnything = true;
14102        }
14103
14104        if (dumpPackage == null) {
14105            pw.println();
14106            needSep = false;
14107            mUserController.dump(pw, dumpAll);
14108        }
14109        if (mHomeProcess != null && (dumpPackage == null
14110                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14111            if (needSep) {
14112                pw.println();
14113                needSep = false;
14114            }
14115            pw.println("  mHomeProcess: " + mHomeProcess);
14116        }
14117        if (mPreviousProcess != null && (dumpPackage == null
14118                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14119            if (needSep) {
14120                pw.println();
14121                needSep = false;
14122            }
14123            pw.println("  mPreviousProcess: " + mPreviousProcess);
14124        }
14125        if (dumpAll) {
14126            StringBuilder sb = new StringBuilder(128);
14127            sb.append("  mPreviousProcessVisibleTime: ");
14128            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14129            pw.println(sb);
14130        }
14131        if (mHeavyWeightProcess != null && (dumpPackage == null
14132                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14133            if (needSep) {
14134                pw.println();
14135                needSep = false;
14136            }
14137            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14138        }
14139        if (dumpPackage == null) {
14140            pw.println("  mConfiguration: " + mConfiguration);
14141        }
14142        if (dumpAll) {
14143            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14144            if (mCompatModePackages.getPackages().size() > 0) {
14145                boolean printed = false;
14146                for (Map.Entry<String, Integer> entry
14147                        : mCompatModePackages.getPackages().entrySet()) {
14148                    String pkg = entry.getKey();
14149                    int mode = entry.getValue();
14150                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14151                        continue;
14152                    }
14153                    if (!printed) {
14154                        pw.println("  mScreenCompatPackages:");
14155                        printed = true;
14156                    }
14157                    pw.print("    "); pw.print(pkg); pw.print(": ");
14158                            pw.print(mode); pw.println();
14159                }
14160            }
14161        }
14162        if (dumpPackage == null) {
14163            pw.println("  mWakefulness="
14164                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14165            pw.println("  mSleepTokens=" + mSleepTokens);
14166            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14167                    + lockScreenShownToString());
14168            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14169            if (mRunningVoice != null) {
14170                pw.println("  mRunningVoice=" + mRunningVoice);
14171                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14172            }
14173        }
14174        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14175                || mOrigWaitForDebugger) {
14176            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14177                    || dumpPackage.equals(mOrigDebugApp)) {
14178                if (needSep) {
14179                    pw.println();
14180                    needSep = false;
14181                }
14182                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14183                        + " mDebugTransient=" + mDebugTransient
14184                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14185            }
14186        }
14187        if (mCurAppTimeTracker != null) {
14188            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14189        }
14190        if (mMemWatchProcesses.getMap().size() > 0) {
14191            pw.println("  Mem watch processes:");
14192            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14193                    = mMemWatchProcesses.getMap();
14194            for (int i=0; i<procs.size(); i++) {
14195                final String proc = procs.keyAt(i);
14196                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14197                for (int j=0; j<uids.size(); j++) {
14198                    if (needSep) {
14199                        pw.println();
14200                        needSep = false;
14201                    }
14202                    StringBuilder sb = new StringBuilder();
14203                    sb.append("    ").append(proc).append('/');
14204                    UserHandle.formatUid(sb, uids.keyAt(j));
14205                    Pair<Long, String> val = uids.valueAt(j);
14206                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14207                    if (val.second != null) {
14208                        sb.append(", report to ").append(val.second);
14209                    }
14210                    pw.println(sb.toString());
14211                }
14212            }
14213            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14214            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14215            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14216                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14217        }
14218        if (mTrackAllocationApp != null) {
14219            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14220                if (needSep) {
14221                    pw.println();
14222                    needSep = false;
14223                }
14224                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14225            }
14226        }
14227        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14228                || mProfileFd != null) {
14229            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14230                if (needSep) {
14231                    pw.println();
14232                    needSep = false;
14233                }
14234                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14235                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14236                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14237                        + mAutoStopProfiler);
14238                pw.println("  mProfileType=" + mProfileType);
14239            }
14240        }
14241        if (mNativeDebuggingApp != null) {
14242            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14243                if (needSep) {
14244                    pw.println();
14245                    needSep = false;
14246                }
14247                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14248            }
14249        }
14250        if (dumpPackage == null) {
14251            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14252                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14253                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14254            }
14255            if (mController != null) {
14256                pw.println("  mController=" + mController
14257                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14258            }
14259            if (dumpAll) {
14260                pw.println("  Total persistent processes: " + numPers);
14261                pw.println("  mProcessesReady=" + mProcessesReady
14262                        + " mSystemReady=" + mSystemReady
14263                        + " mBooted=" + mBooted
14264                        + " mFactoryTest=" + mFactoryTest);
14265                pw.println("  mBooting=" + mBooting
14266                        + " mCallFinishBooting=" + mCallFinishBooting
14267                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14268                pw.print("  mLastPowerCheckRealtime=");
14269                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14270                        pw.println("");
14271                pw.print("  mLastPowerCheckUptime=");
14272                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14273                        pw.println("");
14274                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14275                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14276                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14277                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14278                        + " (" + mLruProcesses.size() + " total)"
14279                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14280                        + " mNumServiceProcs=" + mNumServiceProcs
14281                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14282                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14283                        + " mLastMemoryLevel=" + mLastMemoryLevel
14284                        + " mLastNumProcesses=" + mLastNumProcesses);
14285                long now = SystemClock.uptimeMillis();
14286                pw.print("  mLastIdleTime=");
14287                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14288                        pw.print(" mLowRamSinceLastIdle=");
14289                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14290                        pw.println();
14291            }
14292        }
14293
14294        if (!printedAnything) {
14295            pw.println("  (nothing)");
14296        }
14297    }
14298
14299    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14300            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14301        if (mProcessesToGc.size() > 0) {
14302            boolean printed = false;
14303            long now = SystemClock.uptimeMillis();
14304            for (int i=0; i<mProcessesToGc.size(); i++) {
14305                ProcessRecord proc = mProcessesToGc.get(i);
14306                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14307                    continue;
14308                }
14309                if (!printed) {
14310                    if (needSep) pw.println();
14311                    needSep = true;
14312                    pw.println("  Processes that are waiting to GC:");
14313                    printed = true;
14314                }
14315                pw.print("    Process "); pw.println(proc);
14316                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14317                        pw.print(", last gced=");
14318                        pw.print(now-proc.lastRequestedGc);
14319                        pw.print(" ms ago, last lowMem=");
14320                        pw.print(now-proc.lastLowMemory);
14321                        pw.println(" ms ago");
14322
14323            }
14324        }
14325        return needSep;
14326    }
14327
14328    void printOomLevel(PrintWriter pw, String name, int adj) {
14329        pw.print("    ");
14330        if (adj >= 0) {
14331            pw.print(' ');
14332            if (adj < 10) pw.print(' ');
14333        } else {
14334            if (adj > -10) pw.print(' ');
14335        }
14336        pw.print(adj);
14337        pw.print(": ");
14338        pw.print(name);
14339        pw.print(" (");
14340        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14341        pw.println(")");
14342    }
14343
14344    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14345            int opti, boolean dumpAll) {
14346        boolean needSep = false;
14347
14348        if (mLruProcesses.size() > 0) {
14349            if (needSep) pw.println();
14350            needSep = true;
14351            pw.println("  OOM levels:");
14352            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14353            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14354            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14355            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14356            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14357            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14358            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14359            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14360            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14361            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14362            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14363            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14364            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14365            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14366
14367            if (needSep) pw.println();
14368            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14369                    pw.print(" total, non-act at ");
14370                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14371                    pw.print(", non-svc at ");
14372                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14373                    pw.println("):");
14374            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14375            needSep = true;
14376        }
14377
14378        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14379
14380        pw.println();
14381        pw.println("  mHomeProcess: " + mHomeProcess);
14382        pw.println("  mPreviousProcess: " + mPreviousProcess);
14383        if (mHeavyWeightProcess != null) {
14384            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14385        }
14386
14387        return true;
14388    }
14389
14390    /**
14391     * There are three ways to call this:
14392     *  - no provider specified: dump all the providers
14393     *  - a flattened component name that matched an existing provider was specified as the
14394     *    first arg: dump that one provider
14395     *  - the first arg isn't the flattened component name of an existing provider:
14396     *    dump all providers whose component contains the first arg as a substring
14397     */
14398    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14399            int opti, boolean dumpAll) {
14400        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14401    }
14402
14403    static class ItemMatcher {
14404        ArrayList<ComponentName> components;
14405        ArrayList<String> strings;
14406        ArrayList<Integer> objects;
14407        boolean all;
14408
14409        ItemMatcher() {
14410            all = true;
14411        }
14412
14413        void build(String name) {
14414            ComponentName componentName = ComponentName.unflattenFromString(name);
14415            if (componentName != null) {
14416                if (components == null) {
14417                    components = new ArrayList<ComponentName>();
14418                }
14419                components.add(componentName);
14420                all = false;
14421            } else {
14422                int objectId = 0;
14423                // Not a '/' separated full component name; maybe an object ID?
14424                try {
14425                    objectId = Integer.parseInt(name, 16);
14426                    if (objects == null) {
14427                        objects = new ArrayList<Integer>();
14428                    }
14429                    objects.add(objectId);
14430                    all = false;
14431                } catch (RuntimeException e) {
14432                    // Not an integer; just do string match.
14433                    if (strings == null) {
14434                        strings = new ArrayList<String>();
14435                    }
14436                    strings.add(name);
14437                    all = false;
14438                }
14439            }
14440        }
14441
14442        int build(String[] args, int opti) {
14443            for (; opti<args.length; opti++) {
14444                String name = args[opti];
14445                if ("--".equals(name)) {
14446                    return opti+1;
14447                }
14448                build(name);
14449            }
14450            return opti;
14451        }
14452
14453        boolean match(Object object, ComponentName comp) {
14454            if (all) {
14455                return true;
14456            }
14457            if (components != null) {
14458                for (int i=0; i<components.size(); i++) {
14459                    if (components.get(i).equals(comp)) {
14460                        return true;
14461                    }
14462                }
14463            }
14464            if (objects != null) {
14465                for (int i=0; i<objects.size(); i++) {
14466                    if (System.identityHashCode(object) == objects.get(i)) {
14467                        return true;
14468                    }
14469                }
14470            }
14471            if (strings != null) {
14472                String flat = comp.flattenToString();
14473                for (int i=0; i<strings.size(); i++) {
14474                    if (flat.contains(strings.get(i))) {
14475                        return true;
14476                    }
14477                }
14478            }
14479            return false;
14480        }
14481    }
14482
14483    /**
14484     * There are three things that cmd can be:
14485     *  - a flattened component name that matches an existing activity
14486     *  - the cmd arg isn't the flattened component name of an existing activity:
14487     *    dump all activity whose component contains the cmd as a substring
14488     *  - A hex number of the ActivityRecord object instance.
14489     */
14490    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14491            int opti, boolean dumpAll) {
14492        ArrayList<ActivityRecord> activities;
14493
14494        synchronized (this) {
14495            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14496        }
14497
14498        if (activities.size() <= 0) {
14499            return false;
14500        }
14501
14502        String[] newArgs = new String[args.length - opti];
14503        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14504
14505        TaskRecord lastTask = null;
14506        boolean needSep = false;
14507        for (int i=activities.size()-1; i>=0; i--) {
14508            ActivityRecord r = activities.get(i);
14509            if (needSep) {
14510                pw.println();
14511            }
14512            needSep = true;
14513            synchronized (this) {
14514                if (lastTask != r.task) {
14515                    lastTask = r.task;
14516                    pw.print("TASK "); pw.print(lastTask.affinity);
14517                            pw.print(" id="); pw.println(lastTask.taskId);
14518                    if (dumpAll) {
14519                        lastTask.dump(pw, "  ");
14520                    }
14521                }
14522            }
14523            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14524        }
14525        return true;
14526    }
14527
14528    /**
14529     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14530     * there is a thread associated with the activity.
14531     */
14532    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14533            final ActivityRecord r, String[] args, boolean dumpAll) {
14534        String innerPrefix = prefix + "  ";
14535        synchronized (this) {
14536            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14537                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14538                    pw.print(" pid=");
14539                    if (r.app != null) pw.println(r.app.pid);
14540                    else pw.println("(not running)");
14541            if (dumpAll) {
14542                r.dump(pw, innerPrefix);
14543            }
14544        }
14545        if (r.app != null && r.app.thread != null) {
14546            // flush anything that is already in the PrintWriter since the thread is going
14547            // to write to the file descriptor directly
14548            pw.flush();
14549            try {
14550                TransferPipe tp = new TransferPipe();
14551                try {
14552                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14553                            r.appToken, innerPrefix, args);
14554                    tp.go(fd);
14555                } finally {
14556                    tp.kill();
14557                }
14558            } catch (IOException e) {
14559                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14560            } catch (RemoteException e) {
14561                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14562            }
14563        }
14564    }
14565
14566    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14567            int opti, boolean dumpAll, String dumpPackage) {
14568        boolean needSep = false;
14569        boolean onlyHistory = false;
14570        boolean printedAnything = false;
14571
14572        if ("history".equals(dumpPackage)) {
14573            if (opti < args.length && "-s".equals(args[opti])) {
14574                dumpAll = false;
14575            }
14576            onlyHistory = true;
14577            dumpPackage = null;
14578        }
14579
14580        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14581        if (!onlyHistory && dumpAll) {
14582            if (mRegisteredReceivers.size() > 0) {
14583                boolean printed = false;
14584                Iterator it = mRegisteredReceivers.values().iterator();
14585                while (it.hasNext()) {
14586                    ReceiverList r = (ReceiverList)it.next();
14587                    if (dumpPackage != null && (r.app == null ||
14588                            !dumpPackage.equals(r.app.info.packageName))) {
14589                        continue;
14590                    }
14591                    if (!printed) {
14592                        pw.println("  Registered Receivers:");
14593                        needSep = true;
14594                        printed = true;
14595                        printedAnything = true;
14596                    }
14597                    pw.print("  * "); pw.println(r);
14598                    r.dump(pw, "    ");
14599                }
14600            }
14601
14602            if (mReceiverResolver.dump(pw, needSep ?
14603                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14604                    "    ", dumpPackage, false, false)) {
14605                needSep = true;
14606                printedAnything = true;
14607            }
14608        }
14609
14610        for (BroadcastQueue q : mBroadcastQueues) {
14611            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14612            printedAnything |= needSep;
14613        }
14614
14615        needSep = true;
14616
14617        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14618            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14619                if (needSep) {
14620                    pw.println();
14621                }
14622                needSep = true;
14623                printedAnything = true;
14624                pw.print("  Sticky broadcasts for user ");
14625                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14626                StringBuilder sb = new StringBuilder(128);
14627                for (Map.Entry<String, ArrayList<Intent>> ent
14628                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14629                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14630                    if (dumpAll) {
14631                        pw.println(":");
14632                        ArrayList<Intent> intents = ent.getValue();
14633                        final int N = intents.size();
14634                        for (int i=0; i<N; i++) {
14635                            sb.setLength(0);
14636                            sb.append("    Intent: ");
14637                            intents.get(i).toShortString(sb, false, true, false, false);
14638                            pw.println(sb.toString());
14639                            Bundle bundle = intents.get(i).getExtras();
14640                            if (bundle != null) {
14641                                pw.print("      ");
14642                                pw.println(bundle.toString());
14643                            }
14644                        }
14645                    } else {
14646                        pw.println("");
14647                    }
14648                }
14649            }
14650        }
14651
14652        if (!onlyHistory && dumpAll) {
14653            pw.println();
14654            for (BroadcastQueue queue : mBroadcastQueues) {
14655                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14656                        + queue.mBroadcastsScheduled);
14657            }
14658            pw.println("  mHandler:");
14659            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14660            needSep = true;
14661            printedAnything = true;
14662        }
14663
14664        if (!printedAnything) {
14665            pw.println("  (nothing)");
14666        }
14667    }
14668
14669    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14670            int opti, boolean dumpAll, String dumpPackage) {
14671        boolean needSep;
14672        boolean printedAnything = false;
14673
14674        ItemMatcher matcher = new ItemMatcher();
14675        matcher.build(args, opti);
14676
14677        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14678
14679        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14680        printedAnything |= needSep;
14681
14682        if (mLaunchingProviders.size() > 0) {
14683            boolean printed = false;
14684            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14685                ContentProviderRecord r = mLaunchingProviders.get(i);
14686                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14687                    continue;
14688                }
14689                if (!printed) {
14690                    if (needSep) pw.println();
14691                    needSep = true;
14692                    pw.println("  Launching content providers:");
14693                    printed = true;
14694                    printedAnything = true;
14695                }
14696                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14697                        pw.println(r);
14698            }
14699        }
14700
14701        if (!printedAnything) {
14702            pw.println("  (nothing)");
14703        }
14704    }
14705
14706    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14707            int opti, boolean dumpAll, String dumpPackage) {
14708        boolean needSep = false;
14709        boolean printedAnything = false;
14710
14711        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14712
14713        if (mGrantedUriPermissions.size() > 0) {
14714            boolean printed = false;
14715            int dumpUid = -2;
14716            if (dumpPackage != null) {
14717                try {
14718                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14719                            MATCH_UNINSTALLED_PACKAGES, 0);
14720                } catch (NameNotFoundException e) {
14721                    dumpUid = -1;
14722                }
14723            }
14724            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14725                int uid = mGrantedUriPermissions.keyAt(i);
14726                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14727                    continue;
14728                }
14729                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14730                if (!printed) {
14731                    if (needSep) pw.println();
14732                    needSep = true;
14733                    pw.println("  Granted Uri Permissions:");
14734                    printed = true;
14735                    printedAnything = true;
14736                }
14737                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14738                for (UriPermission perm : perms.values()) {
14739                    pw.print("    "); pw.println(perm);
14740                    if (dumpAll) {
14741                        perm.dump(pw, "      ");
14742                    }
14743                }
14744            }
14745        }
14746
14747        if (!printedAnything) {
14748            pw.println("  (nothing)");
14749        }
14750    }
14751
14752    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14753            int opti, boolean dumpAll, String dumpPackage) {
14754        boolean printed = false;
14755
14756        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14757
14758        if (mIntentSenderRecords.size() > 0) {
14759            Iterator<WeakReference<PendingIntentRecord>> it
14760                    = mIntentSenderRecords.values().iterator();
14761            while (it.hasNext()) {
14762                WeakReference<PendingIntentRecord> ref = it.next();
14763                PendingIntentRecord rec = ref != null ? ref.get(): null;
14764                if (dumpPackage != null && (rec == null
14765                        || !dumpPackage.equals(rec.key.packageName))) {
14766                    continue;
14767                }
14768                printed = true;
14769                if (rec != null) {
14770                    pw.print("  * "); pw.println(rec);
14771                    if (dumpAll) {
14772                        rec.dump(pw, "    ");
14773                    }
14774                } else {
14775                    pw.print("  * "); pw.println(ref);
14776                }
14777            }
14778        }
14779
14780        if (!printed) {
14781            pw.println("  (nothing)");
14782        }
14783    }
14784
14785    private static final int dumpProcessList(PrintWriter pw,
14786            ActivityManagerService service, List list,
14787            String prefix, String normalLabel, String persistentLabel,
14788            String dumpPackage) {
14789        int numPers = 0;
14790        final int N = list.size()-1;
14791        for (int i=N; i>=0; i--) {
14792            ProcessRecord r = (ProcessRecord)list.get(i);
14793            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14794                continue;
14795            }
14796            pw.println(String.format("%s%s #%2d: %s",
14797                    prefix, (r.persistent ? persistentLabel : normalLabel),
14798                    i, r.toString()));
14799            if (r.persistent) {
14800                numPers++;
14801            }
14802        }
14803        return numPers;
14804    }
14805
14806    private static final boolean dumpProcessOomList(PrintWriter pw,
14807            ActivityManagerService service, List<ProcessRecord> origList,
14808            String prefix, String normalLabel, String persistentLabel,
14809            boolean inclDetails, String dumpPackage) {
14810
14811        ArrayList<Pair<ProcessRecord, Integer>> list
14812                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14813        for (int i=0; i<origList.size(); i++) {
14814            ProcessRecord r = origList.get(i);
14815            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14816                continue;
14817            }
14818            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14819        }
14820
14821        if (list.size() <= 0) {
14822            return false;
14823        }
14824
14825        Comparator<Pair<ProcessRecord, Integer>> comparator
14826                = new Comparator<Pair<ProcessRecord, Integer>>() {
14827            @Override
14828            public int compare(Pair<ProcessRecord, Integer> object1,
14829                    Pair<ProcessRecord, Integer> object2) {
14830                if (object1.first.setAdj != object2.first.setAdj) {
14831                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14832                }
14833                if (object1.first.setProcState != object2.first.setProcState) {
14834                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14835                }
14836                if (object1.second.intValue() != object2.second.intValue()) {
14837                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14838                }
14839                return 0;
14840            }
14841        };
14842
14843        Collections.sort(list, comparator);
14844
14845        final long curRealtime = SystemClock.elapsedRealtime();
14846        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14847        final long curUptime = SystemClock.uptimeMillis();
14848        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14849
14850        for (int i=list.size()-1; i>=0; i--) {
14851            ProcessRecord r = list.get(i).first;
14852            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14853            char schedGroup;
14854            switch (r.setSchedGroup) {
14855                case ProcessList.SCHED_GROUP_BACKGROUND:
14856                    schedGroup = 'B';
14857                    break;
14858                case ProcessList.SCHED_GROUP_DEFAULT:
14859                    schedGroup = 'F';
14860                    break;
14861                case ProcessList.SCHED_GROUP_TOP_APP:
14862                    schedGroup = 'T';
14863                    break;
14864                default:
14865                    schedGroup = '?';
14866                    break;
14867            }
14868            char foreground;
14869            if (r.foregroundActivities) {
14870                foreground = 'A';
14871            } else if (r.foregroundServices) {
14872                foreground = 'S';
14873            } else {
14874                foreground = ' ';
14875            }
14876            String procState = ProcessList.makeProcStateString(r.curProcState);
14877            pw.print(prefix);
14878            pw.print(r.persistent ? persistentLabel : normalLabel);
14879            pw.print(" #");
14880            int num = (origList.size()-1)-list.get(i).second;
14881            if (num < 10) pw.print(' ');
14882            pw.print(num);
14883            pw.print(": ");
14884            pw.print(oomAdj);
14885            pw.print(' ');
14886            pw.print(schedGroup);
14887            pw.print('/');
14888            pw.print(foreground);
14889            pw.print('/');
14890            pw.print(procState);
14891            pw.print(" trm:");
14892            if (r.trimMemoryLevel < 10) pw.print(' ');
14893            pw.print(r.trimMemoryLevel);
14894            pw.print(' ');
14895            pw.print(r.toShortString());
14896            pw.print(" (");
14897            pw.print(r.adjType);
14898            pw.println(')');
14899            if (r.adjSource != null || r.adjTarget != null) {
14900                pw.print(prefix);
14901                pw.print("    ");
14902                if (r.adjTarget instanceof ComponentName) {
14903                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14904                } else if (r.adjTarget != null) {
14905                    pw.print(r.adjTarget.toString());
14906                } else {
14907                    pw.print("{null}");
14908                }
14909                pw.print("<=");
14910                if (r.adjSource instanceof ProcessRecord) {
14911                    pw.print("Proc{");
14912                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14913                    pw.println("}");
14914                } else if (r.adjSource != null) {
14915                    pw.println(r.adjSource.toString());
14916                } else {
14917                    pw.println("{null}");
14918                }
14919            }
14920            if (inclDetails) {
14921                pw.print(prefix);
14922                pw.print("    ");
14923                pw.print("oom: max="); pw.print(r.maxAdj);
14924                pw.print(" curRaw="); pw.print(r.curRawAdj);
14925                pw.print(" setRaw="); pw.print(r.setRawAdj);
14926                pw.print(" cur="); pw.print(r.curAdj);
14927                pw.print(" set="); pw.println(r.setAdj);
14928                pw.print(prefix);
14929                pw.print("    ");
14930                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14931                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14932                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14933                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14934                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14935                pw.println();
14936                pw.print(prefix);
14937                pw.print("    ");
14938                pw.print("cached="); pw.print(r.cached);
14939                pw.print(" empty="); pw.print(r.empty);
14940                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14941
14942                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14943                    if (r.lastWakeTime != 0) {
14944                        long wtime;
14945                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14946                        synchronized (stats) {
14947                            wtime = stats.getProcessWakeTime(r.info.uid,
14948                                    r.pid, curRealtime);
14949                        }
14950                        long timeUsed = wtime - r.lastWakeTime;
14951                        pw.print(prefix);
14952                        pw.print("    ");
14953                        pw.print("keep awake over ");
14954                        TimeUtils.formatDuration(realtimeSince, pw);
14955                        pw.print(" used ");
14956                        TimeUtils.formatDuration(timeUsed, pw);
14957                        pw.print(" (");
14958                        pw.print((timeUsed*100)/realtimeSince);
14959                        pw.println("%)");
14960                    }
14961                    if (r.lastCpuTime != 0) {
14962                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14963                        pw.print(prefix);
14964                        pw.print("    ");
14965                        pw.print("run cpu over ");
14966                        TimeUtils.formatDuration(uptimeSince, pw);
14967                        pw.print(" used ");
14968                        TimeUtils.formatDuration(timeUsed, pw);
14969                        pw.print(" (");
14970                        pw.print((timeUsed*100)/uptimeSince);
14971                        pw.println("%)");
14972                    }
14973                }
14974            }
14975        }
14976        return true;
14977    }
14978
14979    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14980            String[] args) {
14981        ArrayList<ProcessRecord> procs;
14982        synchronized (this) {
14983            if (args != null && args.length > start
14984                    && args[start].charAt(0) != '-') {
14985                procs = new ArrayList<ProcessRecord>();
14986                int pid = -1;
14987                try {
14988                    pid = Integer.parseInt(args[start]);
14989                } catch (NumberFormatException e) {
14990                }
14991                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14992                    ProcessRecord proc = mLruProcesses.get(i);
14993                    if (proc.pid == pid) {
14994                        procs.add(proc);
14995                    } else if (allPkgs && proc.pkgList != null
14996                            && proc.pkgList.containsKey(args[start])) {
14997                        procs.add(proc);
14998                    } else if (proc.processName.equals(args[start])) {
14999                        procs.add(proc);
15000                    }
15001                }
15002                if (procs.size() <= 0) {
15003                    return null;
15004                }
15005            } else {
15006                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15007            }
15008        }
15009        return procs;
15010    }
15011
15012    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15013            PrintWriter pw, String[] args) {
15014        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15015        if (procs == null) {
15016            pw.println("No process found for: " + args[0]);
15017            return;
15018        }
15019
15020        long uptime = SystemClock.uptimeMillis();
15021        long realtime = SystemClock.elapsedRealtime();
15022        pw.println("Applications Graphics Acceleration Info:");
15023        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15024
15025        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15026            ProcessRecord r = procs.get(i);
15027            if (r.thread != null) {
15028                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15029                pw.flush();
15030                try {
15031                    TransferPipe tp = new TransferPipe();
15032                    try {
15033                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15034                        tp.go(fd);
15035                    } finally {
15036                        tp.kill();
15037                    }
15038                } catch (IOException e) {
15039                    pw.println("Failure while dumping the app: " + r);
15040                    pw.flush();
15041                } catch (RemoteException e) {
15042                    pw.println("Got a RemoteException while dumping the app " + r);
15043                    pw.flush();
15044                }
15045            }
15046        }
15047    }
15048
15049    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15050        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15051        if (procs == null) {
15052            pw.println("No process found for: " + args[0]);
15053            return;
15054        }
15055
15056        pw.println("Applications Database Info:");
15057
15058        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15059            ProcessRecord r = procs.get(i);
15060            if (r.thread != null) {
15061                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15062                pw.flush();
15063                try {
15064                    TransferPipe tp = new TransferPipe();
15065                    try {
15066                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15067                        tp.go(fd);
15068                    } finally {
15069                        tp.kill();
15070                    }
15071                } catch (IOException e) {
15072                    pw.println("Failure while dumping the app: " + r);
15073                    pw.flush();
15074                } catch (RemoteException e) {
15075                    pw.println("Got a RemoteException while dumping the app " + r);
15076                    pw.flush();
15077                }
15078            }
15079        }
15080    }
15081
15082    final static class MemItem {
15083        final boolean isProc;
15084        final String label;
15085        final String shortLabel;
15086        final long pss;
15087        final long swapPss;
15088        final int id;
15089        final boolean hasActivities;
15090        ArrayList<MemItem> subitems;
15091
15092        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15093                boolean _hasActivities) {
15094            isProc = true;
15095            label = _label;
15096            shortLabel = _shortLabel;
15097            pss = _pss;
15098            swapPss = _swapPss;
15099            id = _id;
15100            hasActivities = _hasActivities;
15101        }
15102
15103        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15104            isProc = false;
15105            label = _label;
15106            shortLabel = _shortLabel;
15107            pss = _pss;
15108            swapPss = _swapPss;
15109            id = _id;
15110            hasActivities = false;
15111        }
15112    }
15113
15114    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15115            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15116        if (sort && !isCompact) {
15117            Collections.sort(items, new Comparator<MemItem>() {
15118                @Override
15119                public int compare(MemItem lhs, MemItem rhs) {
15120                    if (lhs.pss < rhs.pss) {
15121                        return 1;
15122                    } else if (lhs.pss > rhs.pss) {
15123                        return -1;
15124                    }
15125                    return 0;
15126                }
15127            });
15128        }
15129
15130        for (int i=0; i<items.size(); i++) {
15131            MemItem mi = items.get(i);
15132            if (!isCompact) {
15133                if (dumpSwapPss) {
15134                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15135                            mi.label, stringifyKBSize(mi.swapPss));
15136                } else {
15137                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15138                }
15139            } else if (mi.isProc) {
15140                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15141                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15142                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15143                pw.println(mi.hasActivities ? ",a" : ",e");
15144            } else {
15145                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15146                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15147            }
15148            if (mi.subitems != null) {
15149                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15150                        true, isCompact, dumpSwapPss);
15151            }
15152        }
15153    }
15154
15155    // These are in KB.
15156    static final long[] DUMP_MEM_BUCKETS = new long[] {
15157        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15158        120*1024, 160*1024, 200*1024,
15159        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15160        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15161    };
15162
15163    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15164            boolean stackLike) {
15165        int start = label.lastIndexOf('.');
15166        if (start >= 0) start++;
15167        else start = 0;
15168        int end = label.length();
15169        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15170            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15171                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15172                out.append(bucket);
15173                out.append(stackLike ? "MB." : "MB ");
15174                out.append(label, start, end);
15175                return;
15176            }
15177        }
15178        out.append(memKB/1024);
15179        out.append(stackLike ? "MB." : "MB ");
15180        out.append(label, start, end);
15181    }
15182
15183    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15184            ProcessList.NATIVE_ADJ,
15185            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15186            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15187            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15188            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15189            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15190            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15191    };
15192    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15193            "Native",
15194            "System", "Persistent", "Persistent Service", "Foreground",
15195            "Visible", "Perceptible",
15196            "Heavy Weight", "Backup",
15197            "A Services", "Home",
15198            "Previous", "B Services", "Cached"
15199    };
15200    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15201            "native",
15202            "sys", "pers", "persvc", "fore",
15203            "vis", "percept",
15204            "heavy", "backup",
15205            "servicea", "home",
15206            "prev", "serviceb", "cached"
15207    };
15208
15209    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15210            long realtime, boolean isCheckinRequest, boolean isCompact) {
15211        if (isCompact) {
15212            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15213        }
15214        if (isCheckinRequest || isCompact) {
15215            // short checkin version
15216            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15217        } else {
15218            pw.println("Applications Memory Usage (in Kilobytes):");
15219            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15220        }
15221    }
15222
15223    private static final int KSM_SHARED = 0;
15224    private static final int KSM_SHARING = 1;
15225    private static final int KSM_UNSHARED = 2;
15226    private static final int KSM_VOLATILE = 3;
15227
15228    private final long[] getKsmInfo() {
15229        long[] longOut = new long[4];
15230        final int[] SINGLE_LONG_FORMAT = new int[] {
15231            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15232        };
15233        long[] longTmp = new long[1];
15234        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15235                SINGLE_LONG_FORMAT, null, longTmp, null);
15236        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15237        longTmp[0] = 0;
15238        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15239                SINGLE_LONG_FORMAT, null, longTmp, null);
15240        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15241        longTmp[0] = 0;
15242        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15243                SINGLE_LONG_FORMAT, null, longTmp, null);
15244        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15245        longTmp[0] = 0;
15246        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15247                SINGLE_LONG_FORMAT, null, longTmp, null);
15248        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15249        return longOut;
15250    }
15251
15252    private static String stringifySize(long size, int order) {
15253        Locale locale = Locale.US;
15254        switch (order) {
15255            case 1:
15256                return String.format(locale, "%,13d", size);
15257            case 1024:
15258                return String.format(locale, "%,9dK", size / 1024);
15259            case 1024 * 1024:
15260                return String.format(locale, "%,5dM", size / 1024 / 1024);
15261            case 1024 * 1024 * 1024:
15262                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15263            default:
15264                throw new IllegalArgumentException("Invalid size order");
15265        }
15266    }
15267
15268    private static String stringifyKBSize(long size) {
15269        return stringifySize(size * 1024, 1024);
15270    }
15271
15272    // Update this version number in case you change the 'compact' format
15273    private static final int MEMINFO_COMPACT_VERSION = 1;
15274
15275    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15276            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15277        boolean dumpDetails = false;
15278        boolean dumpFullDetails = false;
15279        boolean dumpDalvik = false;
15280        boolean dumpSummaryOnly = false;
15281        boolean dumpUnreachable = false;
15282        boolean oomOnly = false;
15283        boolean isCompact = false;
15284        boolean localOnly = false;
15285        boolean packages = false;
15286        boolean isCheckinRequest = false;
15287        boolean dumpSwapPss = false;
15288
15289        int opti = 0;
15290        while (opti < args.length) {
15291            String opt = args[opti];
15292            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15293                break;
15294            }
15295            opti++;
15296            if ("-a".equals(opt)) {
15297                dumpDetails = true;
15298                dumpFullDetails = true;
15299                dumpDalvik = true;
15300                dumpSwapPss = true;
15301            } else if ("-d".equals(opt)) {
15302                dumpDalvik = true;
15303            } else if ("-c".equals(opt)) {
15304                isCompact = true;
15305            } else if ("-s".equals(opt)) {
15306                dumpDetails = true;
15307                dumpSummaryOnly = true;
15308            } else if ("-S".equals(opt)) {
15309                dumpSwapPss = true;
15310            } else if ("--unreachable".equals(opt)) {
15311                dumpUnreachable = true;
15312            } else if ("--oom".equals(opt)) {
15313                oomOnly = true;
15314            } else if ("--local".equals(opt)) {
15315                localOnly = true;
15316            } else if ("--package".equals(opt)) {
15317                packages = true;
15318            } else if ("--checkin".equals(opt)) {
15319                isCheckinRequest = true;
15320
15321            } else if ("-h".equals(opt)) {
15322                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15323                pw.println("  -a: include all available information for each process.");
15324                pw.println("  -d: include dalvik details.");
15325                pw.println("  -c: dump in a compact machine-parseable representation.");
15326                pw.println("  -s: dump only summary of application memory usage.");
15327                pw.println("  -S: dump also SwapPss.");
15328                pw.println("  --oom: only show processes organized by oom adj.");
15329                pw.println("  --local: only collect details locally, don't call process.");
15330                pw.println("  --package: interpret process arg as package, dumping all");
15331                pw.println("             processes that have loaded that package.");
15332                pw.println("  --checkin: dump data for a checkin");
15333                pw.println("If [process] is specified it can be the name or ");
15334                pw.println("pid of a specific process to dump.");
15335                return;
15336            } else {
15337                pw.println("Unknown argument: " + opt + "; use -h for help");
15338            }
15339        }
15340
15341        long uptime = SystemClock.uptimeMillis();
15342        long realtime = SystemClock.elapsedRealtime();
15343        final long[] tmpLong = new long[1];
15344
15345        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15346        if (procs == null) {
15347            // No Java processes.  Maybe they want to print a native process.
15348            if (args != null && args.length > opti
15349                    && args[opti].charAt(0) != '-') {
15350                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15351                        = new ArrayList<ProcessCpuTracker.Stats>();
15352                updateCpuStatsNow();
15353                int findPid = -1;
15354                try {
15355                    findPid = Integer.parseInt(args[opti]);
15356                } catch (NumberFormatException e) {
15357                }
15358                synchronized (mProcessCpuTracker) {
15359                    final int N = mProcessCpuTracker.countStats();
15360                    for (int i=0; i<N; i++) {
15361                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15362                        if (st.pid == findPid || (st.baseName != null
15363                                && st.baseName.equals(args[opti]))) {
15364                            nativeProcs.add(st);
15365                        }
15366                    }
15367                }
15368                if (nativeProcs.size() > 0) {
15369                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15370                            isCompact);
15371                    Debug.MemoryInfo mi = null;
15372                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15373                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15374                        final int pid = r.pid;
15375                        if (!isCheckinRequest && dumpDetails) {
15376                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15377                        }
15378                        if (mi == null) {
15379                            mi = new Debug.MemoryInfo();
15380                        }
15381                        if (dumpDetails || (!brief && !oomOnly)) {
15382                            Debug.getMemoryInfo(pid, mi);
15383                        } else {
15384                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15385                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15386                        }
15387                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15388                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15389                        if (isCheckinRequest) {
15390                            pw.println();
15391                        }
15392                    }
15393                    return;
15394                }
15395            }
15396            pw.println("No process found for: " + args[opti]);
15397            return;
15398        }
15399
15400        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15401            dumpDetails = true;
15402        }
15403
15404        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15405
15406        String[] innerArgs = new String[args.length-opti];
15407        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15408
15409        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15410        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15411        long nativePss = 0;
15412        long nativeSwapPss = 0;
15413        long dalvikPss = 0;
15414        long dalvikSwapPss = 0;
15415        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15416                EmptyArray.LONG;
15417        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15418                EmptyArray.LONG;
15419        long otherPss = 0;
15420        long otherSwapPss = 0;
15421        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15422        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15423
15424        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15425        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15426        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15427                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15428
15429        long totalPss = 0;
15430        long totalSwapPss = 0;
15431        long cachedPss = 0;
15432        long cachedSwapPss = 0;
15433        boolean hasSwapPss = false;
15434
15435        Debug.MemoryInfo mi = null;
15436        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15437            final ProcessRecord r = procs.get(i);
15438            final IApplicationThread thread;
15439            final int pid;
15440            final int oomAdj;
15441            final boolean hasActivities;
15442            synchronized (this) {
15443                thread = r.thread;
15444                pid = r.pid;
15445                oomAdj = r.getSetAdjWithServices();
15446                hasActivities = r.activities.size() > 0;
15447            }
15448            if (thread != null) {
15449                if (!isCheckinRequest && dumpDetails) {
15450                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15451                }
15452                if (mi == null) {
15453                    mi = new Debug.MemoryInfo();
15454                }
15455                if (dumpDetails || (!brief && !oomOnly)) {
15456                    Debug.getMemoryInfo(pid, mi);
15457                    hasSwapPss = mi.hasSwappedOutPss;
15458                } else {
15459                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15460                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15461                }
15462                if (dumpDetails) {
15463                    if (localOnly) {
15464                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15465                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15466                        if (isCheckinRequest) {
15467                            pw.println();
15468                        }
15469                    } else {
15470                        try {
15471                            pw.flush();
15472                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15473                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15474                        } catch (RemoteException e) {
15475                            if (!isCheckinRequest) {
15476                                pw.println("Got RemoteException!");
15477                                pw.flush();
15478                            }
15479                        }
15480                    }
15481                }
15482
15483                final long myTotalPss = mi.getTotalPss();
15484                final long myTotalUss = mi.getTotalUss();
15485                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15486
15487                synchronized (this) {
15488                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15489                        // Record this for posterity if the process has been stable.
15490                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15491                    }
15492                }
15493
15494                if (!isCheckinRequest && mi != null) {
15495                    totalPss += myTotalPss;
15496                    totalSwapPss += myTotalSwapPss;
15497                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15498                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15499                            myTotalSwapPss, pid, hasActivities);
15500                    procMems.add(pssItem);
15501                    procMemsMap.put(pid, pssItem);
15502
15503                    nativePss += mi.nativePss;
15504                    nativeSwapPss += mi.nativeSwappedOutPss;
15505                    dalvikPss += mi.dalvikPss;
15506                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15507                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15508                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15509                        dalvikSubitemSwapPss[j] +=
15510                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15511                    }
15512                    otherPss += mi.otherPss;
15513                    otherSwapPss += mi.otherSwappedOutPss;
15514                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15515                        long mem = mi.getOtherPss(j);
15516                        miscPss[j] += mem;
15517                        otherPss -= mem;
15518                        mem = mi.getOtherSwappedOutPss(j);
15519                        miscSwapPss[j] += mem;
15520                        otherSwapPss -= mem;
15521                    }
15522
15523                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15524                        cachedPss += myTotalPss;
15525                        cachedSwapPss += myTotalSwapPss;
15526                    }
15527
15528                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15529                        if (oomIndex == (oomPss.length - 1)
15530                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15531                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15532                            oomPss[oomIndex] += myTotalPss;
15533                            oomSwapPss[oomIndex] += myTotalSwapPss;
15534                            if (oomProcs[oomIndex] == null) {
15535                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15536                            }
15537                            oomProcs[oomIndex].add(pssItem);
15538                            break;
15539                        }
15540                    }
15541                }
15542            }
15543        }
15544
15545        long nativeProcTotalPss = 0;
15546
15547        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15548            // If we are showing aggregations, also look for native processes to
15549            // include so that our aggregations are more accurate.
15550            updateCpuStatsNow();
15551            mi = null;
15552            synchronized (mProcessCpuTracker) {
15553                final int N = mProcessCpuTracker.countStats();
15554                for (int i=0; i<N; i++) {
15555                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15556                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15557                        if (mi == null) {
15558                            mi = new Debug.MemoryInfo();
15559                        }
15560                        if (!brief && !oomOnly) {
15561                            Debug.getMemoryInfo(st.pid, mi);
15562                        } else {
15563                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15564                            mi.nativePrivateDirty = (int)tmpLong[0];
15565                        }
15566
15567                        final long myTotalPss = mi.getTotalPss();
15568                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15569                        totalPss += myTotalPss;
15570                        nativeProcTotalPss += myTotalPss;
15571
15572                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15573                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15574                        procMems.add(pssItem);
15575
15576                        nativePss += mi.nativePss;
15577                        nativeSwapPss += mi.nativeSwappedOutPss;
15578                        dalvikPss += mi.dalvikPss;
15579                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15580                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15581                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15582                            dalvikSubitemSwapPss[j] +=
15583                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15584                        }
15585                        otherPss += mi.otherPss;
15586                        otherSwapPss += mi.otherSwappedOutPss;
15587                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15588                            long mem = mi.getOtherPss(j);
15589                            miscPss[j] += mem;
15590                            otherPss -= mem;
15591                            mem = mi.getOtherSwappedOutPss(j);
15592                            miscSwapPss[j] += mem;
15593                            otherSwapPss -= mem;
15594                        }
15595                        oomPss[0] += myTotalPss;
15596                        oomSwapPss[0] += myTotalSwapPss;
15597                        if (oomProcs[0] == null) {
15598                            oomProcs[0] = new ArrayList<MemItem>();
15599                        }
15600                        oomProcs[0].add(pssItem);
15601                    }
15602                }
15603            }
15604
15605            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15606
15607            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15608            final MemItem dalvikItem =
15609                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15610            if (dalvikSubitemPss.length > 0) {
15611                dalvikItem.subitems = new ArrayList<MemItem>();
15612                for (int j=0; j<dalvikSubitemPss.length; j++) {
15613                    final String name = Debug.MemoryInfo.getOtherLabel(
15614                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15615                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15616                                    dalvikSubitemSwapPss[j], j));
15617                }
15618            }
15619            catMems.add(dalvikItem);
15620            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15621            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15622                String label = Debug.MemoryInfo.getOtherLabel(j);
15623                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15624            }
15625
15626            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15627            for (int j=0; j<oomPss.length; j++) {
15628                if (oomPss[j] != 0) {
15629                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15630                            : DUMP_MEM_OOM_LABEL[j];
15631                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15632                            DUMP_MEM_OOM_ADJ[j]);
15633                    item.subitems = oomProcs[j];
15634                    oomMems.add(item);
15635                }
15636            }
15637
15638            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15639            if (!brief && !oomOnly && !isCompact) {
15640                pw.println();
15641                pw.println("Total PSS by process:");
15642                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15643                pw.println();
15644            }
15645            if (!isCompact) {
15646                pw.println("Total PSS by OOM adjustment:");
15647            }
15648            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15649            if (!brief && !oomOnly) {
15650                PrintWriter out = categoryPw != null ? categoryPw : pw;
15651                if (!isCompact) {
15652                    out.println();
15653                    out.println("Total PSS by category:");
15654                }
15655                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15656            }
15657            if (!isCompact) {
15658                pw.println();
15659            }
15660            MemInfoReader memInfo = new MemInfoReader();
15661            memInfo.readMemInfo();
15662            if (nativeProcTotalPss > 0) {
15663                synchronized (this) {
15664                    final long cachedKb = memInfo.getCachedSizeKb();
15665                    final long freeKb = memInfo.getFreeSizeKb();
15666                    final long zramKb = memInfo.getZramTotalSizeKb();
15667                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15668                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15669                            kernelKb*1024, nativeProcTotalPss*1024);
15670                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15671                            nativeProcTotalPss);
15672                }
15673            }
15674            if (!brief) {
15675                if (!isCompact) {
15676                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15677                    pw.print(" (status ");
15678                    switch (mLastMemoryLevel) {
15679                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15680                            pw.println("normal)");
15681                            break;
15682                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15683                            pw.println("moderate)");
15684                            break;
15685                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15686                            pw.println("low)");
15687                            break;
15688                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15689                            pw.println("critical)");
15690                            break;
15691                        default:
15692                            pw.print(mLastMemoryLevel);
15693                            pw.println(")");
15694                            break;
15695                    }
15696                    pw.print(" Free RAM: ");
15697                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15698                            + memInfo.getFreeSizeKb()));
15699                    pw.print(" (");
15700                    pw.print(stringifyKBSize(cachedPss));
15701                    pw.print(" cached pss + ");
15702                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15703                    pw.print(" cached kernel + ");
15704                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15705                    pw.println(" free)");
15706                } else {
15707                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15708                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15709                            + memInfo.getFreeSizeKb()); pw.print(",");
15710                    pw.println(totalPss - cachedPss);
15711                }
15712            }
15713            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15714                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15715                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15716            if (!isCompact) {
15717                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15718                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15719                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15720                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15721                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15722            } else {
15723                pw.print("lostram,"); pw.println(lostRAM);
15724            }
15725            if (!brief) {
15726                if (memInfo.getZramTotalSizeKb() != 0) {
15727                    if (!isCompact) {
15728                        pw.print("     ZRAM: ");
15729                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15730                                pw.print(" physical used for ");
15731                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15732                                        - memInfo.getSwapFreeSizeKb()));
15733                                pw.print(" in swap (");
15734                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15735                                pw.println(" total swap)");
15736                    } else {
15737                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15738                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15739                                pw.println(memInfo.getSwapFreeSizeKb());
15740                    }
15741                }
15742                final long[] ksm = getKsmInfo();
15743                if (!isCompact) {
15744                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15745                            || ksm[KSM_VOLATILE] != 0) {
15746                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15747                                pw.print(" saved from shared ");
15748                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15749                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15750                                pw.print(" unshared; ");
15751                                pw.print(stringifyKBSize(
15752                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15753                    }
15754                    pw.print("   Tuning: ");
15755                    pw.print(ActivityManager.staticGetMemoryClass());
15756                    pw.print(" (large ");
15757                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15758                    pw.print("), oom ");
15759                    pw.print(stringifySize(
15760                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15761                    pw.print(", restore limit ");
15762                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15763                    if (ActivityManager.isLowRamDeviceStatic()) {
15764                        pw.print(" (low-ram)");
15765                    }
15766                    if (ActivityManager.isHighEndGfx()) {
15767                        pw.print(" (high-end-gfx)");
15768                    }
15769                    pw.println();
15770                } else {
15771                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15772                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15773                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15774                    pw.print("tuning,");
15775                    pw.print(ActivityManager.staticGetMemoryClass());
15776                    pw.print(',');
15777                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15778                    pw.print(',');
15779                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15780                    if (ActivityManager.isLowRamDeviceStatic()) {
15781                        pw.print(",low-ram");
15782                    }
15783                    if (ActivityManager.isHighEndGfx()) {
15784                        pw.print(",high-end-gfx");
15785                    }
15786                    pw.println();
15787                }
15788            }
15789        }
15790    }
15791
15792    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15793            long memtrack, String name) {
15794        sb.append("  ");
15795        sb.append(ProcessList.makeOomAdjString(oomAdj));
15796        sb.append(' ');
15797        sb.append(ProcessList.makeProcStateString(procState));
15798        sb.append(' ');
15799        ProcessList.appendRamKb(sb, pss);
15800        sb.append(": ");
15801        sb.append(name);
15802        if (memtrack > 0) {
15803            sb.append(" (");
15804            sb.append(stringifyKBSize(memtrack));
15805            sb.append(" memtrack)");
15806        }
15807    }
15808
15809    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15810        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15811        sb.append(" (pid ");
15812        sb.append(mi.pid);
15813        sb.append(") ");
15814        sb.append(mi.adjType);
15815        sb.append('\n');
15816        if (mi.adjReason != null) {
15817            sb.append("                      ");
15818            sb.append(mi.adjReason);
15819            sb.append('\n');
15820        }
15821    }
15822
15823    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15824        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15825        for (int i=0, N=memInfos.size(); i<N; i++) {
15826            ProcessMemInfo mi = memInfos.get(i);
15827            infoMap.put(mi.pid, mi);
15828        }
15829        updateCpuStatsNow();
15830        long[] memtrackTmp = new long[1];
15831        synchronized (mProcessCpuTracker) {
15832            final int N = mProcessCpuTracker.countStats();
15833            for (int i=0; i<N; i++) {
15834                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15835                if (st.vsize > 0) {
15836                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15837                    if (pss > 0) {
15838                        if (infoMap.indexOfKey(st.pid) < 0) {
15839                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15840                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15841                            mi.pss = pss;
15842                            mi.memtrack = memtrackTmp[0];
15843                            memInfos.add(mi);
15844                        }
15845                    }
15846                }
15847            }
15848        }
15849
15850        long totalPss = 0;
15851        long totalMemtrack = 0;
15852        for (int i=0, N=memInfos.size(); i<N; i++) {
15853            ProcessMemInfo mi = memInfos.get(i);
15854            if (mi.pss == 0) {
15855                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15856                mi.memtrack = memtrackTmp[0];
15857            }
15858            totalPss += mi.pss;
15859            totalMemtrack += mi.memtrack;
15860        }
15861        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15862            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15863                if (lhs.oomAdj != rhs.oomAdj) {
15864                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15865                }
15866                if (lhs.pss != rhs.pss) {
15867                    return lhs.pss < rhs.pss ? 1 : -1;
15868                }
15869                return 0;
15870            }
15871        });
15872
15873        StringBuilder tag = new StringBuilder(128);
15874        StringBuilder stack = new StringBuilder(128);
15875        tag.append("Low on memory -- ");
15876        appendMemBucket(tag, totalPss, "total", false);
15877        appendMemBucket(stack, totalPss, "total", true);
15878
15879        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15880        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15881        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15882
15883        boolean firstLine = true;
15884        int lastOomAdj = Integer.MIN_VALUE;
15885        long extraNativeRam = 0;
15886        long extraNativeMemtrack = 0;
15887        long cachedPss = 0;
15888        for (int i=0, N=memInfos.size(); i<N; i++) {
15889            ProcessMemInfo mi = memInfos.get(i);
15890
15891            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15892                cachedPss += mi.pss;
15893            }
15894
15895            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15896                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15897                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15898                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15899                if (lastOomAdj != mi.oomAdj) {
15900                    lastOomAdj = mi.oomAdj;
15901                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15902                        tag.append(" / ");
15903                    }
15904                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15905                        if (firstLine) {
15906                            stack.append(":");
15907                            firstLine = false;
15908                        }
15909                        stack.append("\n\t at ");
15910                    } else {
15911                        stack.append("$");
15912                    }
15913                } else {
15914                    tag.append(" ");
15915                    stack.append("$");
15916                }
15917                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15918                    appendMemBucket(tag, mi.pss, mi.name, false);
15919                }
15920                appendMemBucket(stack, mi.pss, mi.name, true);
15921                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15922                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15923                    stack.append("(");
15924                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15925                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15926                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15927                            stack.append(":");
15928                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15929                        }
15930                    }
15931                    stack.append(")");
15932                }
15933            }
15934
15935            appendMemInfo(fullNativeBuilder, mi);
15936            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15937                // The short form only has native processes that are >= 512K.
15938                if (mi.pss >= 512) {
15939                    appendMemInfo(shortNativeBuilder, mi);
15940                } else {
15941                    extraNativeRam += mi.pss;
15942                    extraNativeMemtrack += mi.memtrack;
15943                }
15944            } else {
15945                // Short form has all other details, but if we have collected RAM
15946                // from smaller native processes let's dump a summary of that.
15947                if (extraNativeRam > 0) {
15948                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15949                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15950                    shortNativeBuilder.append('\n');
15951                    extraNativeRam = 0;
15952                }
15953                appendMemInfo(fullJavaBuilder, mi);
15954            }
15955        }
15956
15957        fullJavaBuilder.append("           ");
15958        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15959        fullJavaBuilder.append(": TOTAL");
15960        if (totalMemtrack > 0) {
15961            fullJavaBuilder.append(" (");
15962            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15963            fullJavaBuilder.append(" memtrack)");
15964        } else {
15965        }
15966        fullJavaBuilder.append("\n");
15967
15968        MemInfoReader memInfo = new MemInfoReader();
15969        memInfo.readMemInfo();
15970        final long[] infos = memInfo.getRawInfo();
15971
15972        StringBuilder memInfoBuilder = new StringBuilder(1024);
15973        Debug.getMemInfo(infos);
15974        memInfoBuilder.append("  MemInfo: ");
15975        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15976        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15977        memInfoBuilder.append(stringifyKBSize(
15978                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15979        memInfoBuilder.append(stringifyKBSize(
15980                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15981        memInfoBuilder.append(stringifyKBSize(
15982                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15983        memInfoBuilder.append("           ");
15984        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15985        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15986        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15987        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15988        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15989            memInfoBuilder.append("  ZRAM: ");
15990            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15991            memInfoBuilder.append(" RAM, ");
15992            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15993            memInfoBuilder.append(" swap total, ");
15994            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15995            memInfoBuilder.append(" swap free\n");
15996        }
15997        final long[] ksm = getKsmInfo();
15998        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15999                || ksm[KSM_VOLATILE] != 0) {
16000            memInfoBuilder.append("  KSM: ");
16001            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16002            memInfoBuilder.append(" saved from shared ");
16003            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16004            memInfoBuilder.append("\n       ");
16005            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16006            memInfoBuilder.append(" unshared; ");
16007            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16008            memInfoBuilder.append(" volatile\n");
16009        }
16010        memInfoBuilder.append("  Free RAM: ");
16011        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16012                + memInfo.getFreeSizeKb()));
16013        memInfoBuilder.append("\n");
16014        memInfoBuilder.append("  Used RAM: ");
16015        memInfoBuilder.append(stringifyKBSize(
16016                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16017        memInfoBuilder.append("\n");
16018        memInfoBuilder.append("  Lost RAM: ");
16019        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16020                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16021                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16022        memInfoBuilder.append("\n");
16023        Slog.i(TAG, "Low on memory:");
16024        Slog.i(TAG, shortNativeBuilder.toString());
16025        Slog.i(TAG, fullJavaBuilder.toString());
16026        Slog.i(TAG, memInfoBuilder.toString());
16027
16028        StringBuilder dropBuilder = new StringBuilder(1024);
16029        /*
16030        StringWriter oomSw = new StringWriter();
16031        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16032        StringWriter catSw = new StringWriter();
16033        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16034        String[] emptyArgs = new String[] { };
16035        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16036        oomPw.flush();
16037        String oomString = oomSw.toString();
16038        */
16039        dropBuilder.append("Low on memory:");
16040        dropBuilder.append(stack);
16041        dropBuilder.append('\n');
16042        dropBuilder.append(fullNativeBuilder);
16043        dropBuilder.append(fullJavaBuilder);
16044        dropBuilder.append('\n');
16045        dropBuilder.append(memInfoBuilder);
16046        dropBuilder.append('\n');
16047        /*
16048        dropBuilder.append(oomString);
16049        dropBuilder.append('\n');
16050        */
16051        StringWriter catSw = new StringWriter();
16052        synchronized (ActivityManagerService.this) {
16053            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16054            String[] emptyArgs = new String[] { };
16055            catPw.println();
16056            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16057            catPw.println();
16058            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16059                    false, false, null);
16060            catPw.println();
16061            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16062            catPw.flush();
16063        }
16064        dropBuilder.append(catSw.toString());
16065        addErrorToDropBox("lowmem", null, "system_server", null,
16066                null, tag.toString(), dropBuilder.toString(), null, null);
16067        //Slog.i(TAG, "Sent to dropbox:");
16068        //Slog.i(TAG, dropBuilder.toString());
16069        synchronized (ActivityManagerService.this) {
16070            long now = SystemClock.uptimeMillis();
16071            if (mLastMemUsageReportTime < now) {
16072                mLastMemUsageReportTime = now;
16073            }
16074        }
16075    }
16076
16077    /**
16078     * Searches array of arguments for the specified string
16079     * @param args array of argument strings
16080     * @param value value to search for
16081     * @return true if the value is contained in the array
16082     */
16083    private static boolean scanArgs(String[] args, String value) {
16084        if (args != null) {
16085            for (String arg : args) {
16086                if (value.equals(arg)) {
16087                    return true;
16088                }
16089            }
16090        }
16091        return false;
16092    }
16093
16094    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16095            ContentProviderRecord cpr, boolean always) {
16096        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16097
16098        if (!inLaunching || always) {
16099            synchronized (cpr) {
16100                cpr.launchingApp = null;
16101                cpr.notifyAll();
16102            }
16103            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16104            String names[] = cpr.info.authority.split(";");
16105            for (int j = 0; j < names.length; j++) {
16106                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16107            }
16108        }
16109
16110        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16111            ContentProviderConnection conn = cpr.connections.get(i);
16112            if (conn.waiting) {
16113                // If this connection is waiting for the provider, then we don't
16114                // need to mess with its process unless we are always removing
16115                // or for some reason the provider is not currently launching.
16116                if (inLaunching && !always) {
16117                    continue;
16118                }
16119            }
16120            ProcessRecord capp = conn.client;
16121            conn.dead = true;
16122            if (conn.stableCount > 0) {
16123                if (!capp.persistent && capp.thread != null
16124                        && capp.pid != 0
16125                        && capp.pid != MY_PID) {
16126                    capp.kill("depends on provider "
16127                            + cpr.name.flattenToShortString()
16128                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16129                }
16130            } else if (capp.thread != null && conn.provider.provider != null) {
16131                try {
16132                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16133                } catch (RemoteException e) {
16134                }
16135                // In the protocol here, we don't expect the client to correctly
16136                // clean up this connection, we'll just remove it.
16137                cpr.connections.remove(i);
16138                if (conn.client.conProviders.remove(conn)) {
16139                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16140                }
16141            }
16142        }
16143
16144        if (inLaunching && always) {
16145            mLaunchingProviders.remove(cpr);
16146        }
16147        return inLaunching;
16148    }
16149
16150    /**
16151     * Main code for cleaning up a process when it has gone away.  This is
16152     * called both as a result of the process dying, or directly when stopping
16153     * a process when running in single process mode.
16154     *
16155     * @return Returns true if the given process has been restarted, so the
16156     * app that was passed in must remain on the process lists.
16157     */
16158    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16159            boolean restarting, boolean allowRestart, int index) {
16160        if (index >= 0) {
16161            removeLruProcessLocked(app);
16162            ProcessList.remove(app.pid);
16163        }
16164
16165        mProcessesToGc.remove(app);
16166        mPendingPssProcesses.remove(app);
16167
16168        // Dismiss any open dialogs.
16169        if (app.crashDialog != null && !app.forceCrashReport) {
16170            app.crashDialog.dismiss();
16171            app.crashDialog = null;
16172        }
16173        if (app.anrDialog != null) {
16174            app.anrDialog.dismiss();
16175            app.anrDialog = null;
16176        }
16177        if (app.waitDialog != null) {
16178            app.waitDialog.dismiss();
16179            app.waitDialog = null;
16180        }
16181
16182        app.crashing = false;
16183        app.notResponding = false;
16184
16185        app.resetPackageList(mProcessStats);
16186        app.unlinkDeathRecipient();
16187        app.makeInactive(mProcessStats);
16188        app.waitingToKill = null;
16189        app.forcingToForeground = null;
16190        updateProcessForegroundLocked(app, false, false);
16191        app.foregroundActivities = false;
16192        app.hasShownUi = false;
16193        app.treatLikeActivity = false;
16194        app.hasAboveClient = false;
16195        app.hasClientActivities = false;
16196
16197        mServices.killServicesLocked(app, allowRestart);
16198
16199        boolean restart = false;
16200
16201        // Remove published content providers.
16202        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16203            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16204            final boolean always = app.bad || !allowRestart;
16205            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16206            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16207                // We left the provider in the launching list, need to
16208                // restart it.
16209                restart = true;
16210            }
16211
16212            cpr.provider = null;
16213            cpr.proc = null;
16214        }
16215        app.pubProviders.clear();
16216
16217        // Take care of any launching providers waiting for this process.
16218        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16219            restart = true;
16220        }
16221
16222        // Unregister from connected content providers.
16223        if (!app.conProviders.isEmpty()) {
16224            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16225                ContentProviderConnection conn = app.conProviders.get(i);
16226                conn.provider.connections.remove(conn);
16227                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16228                        conn.provider.name);
16229            }
16230            app.conProviders.clear();
16231        }
16232
16233        // At this point there may be remaining entries in mLaunchingProviders
16234        // where we were the only one waiting, so they are no longer of use.
16235        // Look for these and clean up if found.
16236        // XXX Commented out for now.  Trying to figure out a way to reproduce
16237        // the actual situation to identify what is actually going on.
16238        if (false) {
16239            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16240                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16241                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16242                    synchronized (cpr) {
16243                        cpr.launchingApp = null;
16244                        cpr.notifyAll();
16245                    }
16246                }
16247            }
16248        }
16249
16250        skipCurrentReceiverLocked(app);
16251
16252        // Unregister any receivers.
16253        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16254            removeReceiverLocked(app.receivers.valueAt(i));
16255        }
16256        app.receivers.clear();
16257
16258        // If the app is undergoing backup, tell the backup manager about it
16259        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16260            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16261                    + mBackupTarget.appInfo + " died during backup");
16262            try {
16263                IBackupManager bm = IBackupManager.Stub.asInterface(
16264                        ServiceManager.getService(Context.BACKUP_SERVICE));
16265                bm.agentDisconnected(app.info.packageName);
16266            } catch (RemoteException e) {
16267                // can't happen; backup manager is local
16268            }
16269        }
16270
16271        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16272            ProcessChangeItem item = mPendingProcessChanges.get(i);
16273            if (item.pid == app.pid) {
16274                mPendingProcessChanges.remove(i);
16275                mAvailProcessChanges.add(item);
16276            }
16277        }
16278        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16279                null).sendToTarget();
16280
16281        // If the caller is restarting this app, then leave it in its
16282        // current lists and let the caller take care of it.
16283        if (restarting) {
16284            return false;
16285        }
16286
16287        if (!app.persistent || app.isolated) {
16288            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16289                    "Removing non-persistent process during cleanup: " + app);
16290            removeProcessNameLocked(app.processName, app.uid);
16291            if (mHeavyWeightProcess == app) {
16292                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16293                        mHeavyWeightProcess.userId, 0));
16294                mHeavyWeightProcess = null;
16295            }
16296        } else if (!app.removed) {
16297            // This app is persistent, so we need to keep its record around.
16298            // If it is not already on the pending app list, add it there
16299            // and start a new process for it.
16300            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16301                mPersistentStartingProcesses.add(app);
16302                restart = true;
16303            }
16304        }
16305        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16306                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16307        mProcessesOnHold.remove(app);
16308
16309        if (app == mHomeProcess) {
16310            mHomeProcess = null;
16311        }
16312        if (app == mPreviousProcess) {
16313            mPreviousProcess = null;
16314        }
16315
16316        if (restart && !app.isolated) {
16317            // We have components that still need to be running in the
16318            // process, so re-launch it.
16319            if (index < 0) {
16320                ProcessList.remove(app.pid);
16321            }
16322            addProcessNameLocked(app);
16323            startProcessLocked(app, "restart", app.processName);
16324            return true;
16325        } else if (app.pid > 0 && app.pid != MY_PID) {
16326            // Goodbye!
16327            boolean removed;
16328            synchronized (mPidsSelfLocked) {
16329                mPidsSelfLocked.remove(app.pid);
16330                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16331            }
16332            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16333            if (app.isolated) {
16334                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16335            }
16336            app.setPid(0);
16337        }
16338        return false;
16339    }
16340
16341    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16342        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16343            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16344            if (cpr.launchingApp == app) {
16345                return true;
16346            }
16347        }
16348        return false;
16349    }
16350
16351    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16352        // Look through the content providers we are waiting to have launched,
16353        // and if any run in this process then either schedule a restart of
16354        // the process or kill the client waiting for it if this process has
16355        // gone bad.
16356        boolean restart = false;
16357        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16358            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16359            if (cpr.launchingApp == app) {
16360                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16361                    restart = true;
16362                } else {
16363                    removeDyingProviderLocked(app, cpr, true);
16364                }
16365            }
16366        }
16367        return restart;
16368    }
16369
16370    // =========================================================
16371    // SERVICES
16372    // =========================================================
16373
16374    @Override
16375    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16376            int flags) {
16377        enforceNotIsolatedCaller("getServices");
16378        synchronized (this) {
16379            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16380        }
16381    }
16382
16383    @Override
16384    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16385        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16386        synchronized (this) {
16387            return mServices.getRunningServiceControlPanelLocked(name);
16388        }
16389    }
16390
16391    @Override
16392    public ComponentName startService(IApplicationThread caller, Intent service,
16393            String resolvedType, String callingPackage, int userId)
16394            throws TransactionTooLargeException {
16395        enforceNotIsolatedCaller("startService");
16396        // Refuse possible leaked file descriptors
16397        if (service != null && service.hasFileDescriptors() == true) {
16398            throw new IllegalArgumentException("File descriptors passed in Intent");
16399        }
16400
16401        if (callingPackage == null) {
16402            throw new IllegalArgumentException("callingPackage cannot be null");
16403        }
16404
16405        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16406                "startService: " + service + " type=" + resolvedType);
16407        synchronized(this) {
16408            final int callingPid = Binder.getCallingPid();
16409            final int callingUid = Binder.getCallingUid();
16410            final long origId = Binder.clearCallingIdentity();
16411            ComponentName res = mServices.startServiceLocked(caller, service,
16412                    resolvedType, callingPid, callingUid, callingPackage, userId);
16413            Binder.restoreCallingIdentity(origId);
16414            return res;
16415        }
16416    }
16417
16418    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16419            String callingPackage, int userId)
16420            throws TransactionTooLargeException {
16421        synchronized(this) {
16422            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16423                    "startServiceInPackage: " + service + " type=" + resolvedType);
16424            final long origId = Binder.clearCallingIdentity();
16425            ComponentName res = mServices.startServiceLocked(null, service,
16426                    resolvedType, -1, uid, callingPackage, userId);
16427            Binder.restoreCallingIdentity(origId);
16428            return res;
16429        }
16430    }
16431
16432    @Override
16433    public int stopService(IApplicationThread caller, Intent service,
16434            String resolvedType, int userId) {
16435        enforceNotIsolatedCaller("stopService");
16436        // Refuse possible leaked file descriptors
16437        if (service != null && service.hasFileDescriptors() == true) {
16438            throw new IllegalArgumentException("File descriptors passed in Intent");
16439        }
16440
16441        synchronized(this) {
16442            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16443        }
16444    }
16445
16446    @Override
16447    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16448        enforceNotIsolatedCaller("peekService");
16449        // Refuse possible leaked file descriptors
16450        if (service != null && service.hasFileDescriptors() == true) {
16451            throw new IllegalArgumentException("File descriptors passed in Intent");
16452        }
16453
16454        if (callingPackage == null) {
16455            throw new IllegalArgumentException("callingPackage cannot be null");
16456        }
16457
16458        synchronized(this) {
16459            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16460        }
16461    }
16462
16463    @Override
16464    public boolean stopServiceToken(ComponentName className, IBinder token,
16465            int startId) {
16466        synchronized(this) {
16467            return mServices.stopServiceTokenLocked(className, token, startId);
16468        }
16469    }
16470
16471    @Override
16472    public void setServiceForeground(ComponentName className, IBinder token,
16473            int id, Notification notification, int flags) {
16474        synchronized(this) {
16475            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16476        }
16477    }
16478
16479    @Override
16480    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16481            boolean requireFull, String name, String callerPackage) {
16482        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16483                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16484    }
16485
16486    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16487            String className, int flags) {
16488        boolean result = false;
16489        // For apps that don't have pre-defined UIDs, check for permission
16490        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16491            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16492                if (ActivityManager.checkUidPermission(
16493                        INTERACT_ACROSS_USERS,
16494                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16495                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16496                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16497                            + " requests FLAG_SINGLE_USER, but app does not hold "
16498                            + INTERACT_ACROSS_USERS;
16499                    Slog.w(TAG, msg);
16500                    throw new SecurityException(msg);
16501                }
16502                // Permission passed
16503                result = true;
16504            }
16505        } else if ("system".equals(componentProcessName)) {
16506            result = true;
16507        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16508            // Phone app and persistent apps are allowed to export singleuser providers.
16509            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16510                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16511        }
16512        if (DEBUG_MU) Slog.v(TAG_MU,
16513                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16514                + Integer.toHexString(flags) + ") = " + result);
16515        return result;
16516    }
16517
16518    /**
16519     * Checks to see if the caller is in the same app as the singleton
16520     * component, or the component is in a special app. It allows special apps
16521     * to export singleton components but prevents exporting singleton
16522     * components for regular apps.
16523     */
16524    boolean isValidSingletonCall(int callingUid, int componentUid) {
16525        int componentAppId = UserHandle.getAppId(componentUid);
16526        return UserHandle.isSameApp(callingUid, componentUid)
16527                || componentAppId == Process.SYSTEM_UID
16528                || componentAppId == Process.PHONE_UID
16529                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16530                        == PackageManager.PERMISSION_GRANTED;
16531    }
16532
16533    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16534            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16535            int userId) throws TransactionTooLargeException {
16536        enforceNotIsolatedCaller("bindService");
16537
16538        // Refuse possible leaked file descriptors
16539        if (service != null && service.hasFileDescriptors() == true) {
16540            throw new IllegalArgumentException("File descriptors passed in Intent");
16541        }
16542
16543        if (callingPackage == null) {
16544            throw new IllegalArgumentException("callingPackage cannot be null");
16545        }
16546
16547        synchronized(this) {
16548            return mServices.bindServiceLocked(caller, token, service,
16549                    resolvedType, connection, flags, callingPackage, userId);
16550        }
16551    }
16552
16553    public boolean unbindService(IServiceConnection connection) {
16554        synchronized (this) {
16555            return mServices.unbindServiceLocked(connection);
16556        }
16557    }
16558
16559    public void publishService(IBinder token, Intent intent, IBinder service) {
16560        // Refuse possible leaked file descriptors
16561        if (intent != null && intent.hasFileDescriptors() == true) {
16562            throw new IllegalArgumentException("File descriptors passed in Intent");
16563        }
16564
16565        synchronized(this) {
16566            if (!(token instanceof ServiceRecord)) {
16567                throw new IllegalArgumentException("Invalid service token");
16568            }
16569            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16570        }
16571    }
16572
16573    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16574        // Refuse possible leaked file descriptors
16575        if (intent != null && intent.hasFileDescriptors() == true) {
16576            throw new IllegalArgumentException("File descriptors passed in Intent");
16577        }
16578
16579        synchronized(this) {
16580            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16581        }
16582    }
16583
16584    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16585        synchronized(this) {
16586            if (!(token instanceof ServiceRecord)) {
16587                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16588                throw new IllegalArgumentException("Invalid service token");
16589            }
16590            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16591        }
16592    }
16593
16594    // =========================================================
16595    // BACKUP AND RESTORE
16596    // =========================================================
16597
16598    // Cause the target app to be launched if necessary and its backup agent
16599    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16600    // activity manager to announce its creation.
16601    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16602        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16603                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16604        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16605
16606        synchronized(this) {
16607            // !!! TODO: currently no check here that we're already bound
16608            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16609            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16610            synchronized (stats) {
16611                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16612            }
16613
16614            // Backup agent is now in use, its package can't be stopped.
16615            try {
16616                AppGlobals.getPackageManager().setPackageStoppedState(
16617                        app.packageName, false, UserHandle.getUserId(app.uid));
16618            } catch (RemoteException e) {
16619            } catch (IllegalArgumentException e) {
16620                Slog.w(TAG, "Failed trying to unstop package "
16621                        + app.packageName + ": " + e);
16622            }
16623
16624            BackupRecord r = new BackupRecord(ss, app, backupMode);
16625            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16626                    ? new ComponentName(app.packageName, app.backupAgentName)
16627                    : new ComponentName("android", "FullBackupAgent");
16628            // startProcessLocked() returns existing proc's record if it's already running
16629            ProcessRecord proc = startProcessLocked(app.processName, app,
16630                    false, 0, "backup", hostingName, false, false, false);
16631            if (proc == null) {
16632                Slog.e(TAG, "Unable to start backup agent process " + r);
16633                return false;
16634            }
16635
16636            r.app = proc;
16637            mBackupTarget = r;
16638            mBackupAppName = app.packageName;
16639
16640            // Try not to kill the process during backup
16641            updateOomAdjLocked(proc);
16642
16643            // If the process is already attached, schedule the creation of the backup agent now.
16644            // If it is not yet live, this will be done when it attaches to the framework.
16645            if (proc.thread != null) {
16646                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16647                try {
16648                    proc.thread.scheduleCreateBackupAgent(app,
16649                            compatibilityInfoForPackageLocked(app), backupMode);
16650                } catch (RemoteException e) {
16651                    // Will time out on the backup manager side
16652                }
16653            } else {
16654                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16655            }
16656            // Invariants: at this point, the target app process exists and the application
16657            // is either already running or in the process of coming up.  mBackupTarget and
16658            // mBackupAppName describe the app, so that when it binds back to the AM we
16659            // know that it's scheduled for a backup-agent operation.
16660        }
16661
16662        return true;
16663    }
16664
16665    @Override
16666    public void clearPendingBackup() {
16667        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16668        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16669
16670        synchronized (this) {
16671            mBackupTarget = null;
16672            mBackupAppName = null;
16673        }
16674    }
16675
16676    // A backup agent has just come up
16677    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16678        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16679                + " = " + agent);
16680
16681        synchronized(this) {
16682            if (!agentPackageName.equals(mBackupAppName)) {
16683                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16684                return;
16685            }
16686        }
16687
16688        long oldIdent = Binder.clearCallingIdentity();
16689        try {
16690            IBackupManager bm = IBackupManager.Stub.asInterface(
16691                    ServiceManager.getService(Context.BACKUP_SERVICE));
16692            bm.agentConnected(agentPackageName, agent);
16693        } catch (RemoteException e) {
16694            // can't happen; the backup manager service is local
16695        } catch (Exception e) {
16696            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16697            e.printStackTrace();
16698        } finally {
16699            Binder.restoreCallingIdentity(oldIdent);
16700        }
16701    }
16702
16703    // done with this agent
16704    public void unbindBackupAgent(ApplicationInfo appInfo) {
16705        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16706        if (appInfo == null) {
16707            Slog.w(TAG, "unbind backup agent for null app");
16708            return;
16709        }
16710
16711        synchronized(this) {
16712            try {
16713                if (mBackupAppName == null) {
16714                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16715                    return;
16716                }
16717
16718                if (!mBackupAppName.equals(appInfo.packageName)) {
16719                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16720                    return;
16721                }
16722
16723                // Not backing this app up any more; reset its OOM adjustment
16724                final ProcessRecord proc = mBackupTarget.app;
16725                updateOomAdjLocked(proc);
16726
16727                // If the app crashed during backup, 'thread' will be null here
16728                if (proc.thread != null) {
16729                    try {
16730                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16731                                compatibilityInfoForPackageLocked(appInfo));
16732                    } catch (Exception e) {
16733                        Slog.e(TAG, "Exception when unbinding backup agent:");
16734                        e.printStackTrace();
16735                    }
16736                }
16737            } finally {
16738                mBackupTarget = null;
16739                mBackupAppName = null;
16740            }
16741        }
16742    }
16743    // =========================================================
16744    // BROADCASTS
16745    // =========================================================
16746
16747    boolean isPendingBroadcastProcessLocked(int pid) {
16748        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16749                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16750    }
16751
16752    void skipPendingBroadcastLocked(int pid) {
16753            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16754            for (BroadcastQueue queue : mBroadcastQueues) {
16755                queue.skipPendingBroadcastLocked(pid);
16756            }
16757    }
16758
16759    // The app just attached; send any pending broadcasts that it should receive
16760    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16761        boolean didSomething = false;
16762        for (BroadcastQueue queue : mBroadcastQueues) {
16763            didSomething |= queue.sendPendingBroadcastsLocked(app);
16764        }
16765        return didSomething;
16766    }
16767
16768    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16769            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16770        enforceNotIsolatedCaller("registerReceiver");
16771        ArrayList<Intent> stickyIntents = null;
16772        ProcessRecord callerApp = null;
16773        int callingUid;
16774        int callingPid;
16775        synchronized(this) {
16776            if (caller != null) {
16777                callerApp = getRecordForAppLocked(caller);
16778                if (callerApp == null) {
16779                    throw new SecurityException(
16780                            "Unable to find app for caller " + caller
16781                            + " (pid=" + Binder.getCallingPid()
16782                            + ") when registering receiver " + receiver);
16783                }
16784                if (callerApp.info.uid != Process.SYSTEM_UID &&
16785                        !callerApp.pkgList.containsKey(callerPackage) &&
16786                        !"android".equals(callerPackage)) {
16787                    throw new SecurityException("Given caller package " + callerPackage
16788                            + " is not running in process " + callerApp);
16789                }
16790                callingUid = callerApp.info.uid;
16791                callingPid = callerApp.pid;
16792            } else {
16793                callerPackage = null;
16794                callingUid = Binder.getCallingUid();
16795                callingPid = Binder.getCallingPid();
16796            }
16797
16798            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16799                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16800
16801            Iterator<String> actions = filter.actionsIterator();
16802            if (actions == null) {
16803                ArrayList<String> noAction = new ArrayList<String>(1);
16804                noAction.add(null);
16805                actions = noAction.iterator();
16806            }
16807
16808            // Collect stickies of users
16809            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16810            while (actions.hasNext()) {
16811                String action = actions.next();
16812                for (int id : userIds) {
16813                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16814                    if (stickies != null) {
16815                        ArrayList<Intent> intents = stickies.get(action);
16816                        if (intents != null) {
16817                            if (stickyIntents == null) {
16818                                stickyIntents = new ArrayList<Intent>();
16819                            }
16820                            stickyIntents.addAll(intents);
16821                        }
16822                    }
16823                }
16824            }
16825        }
16826
16827        ArrayList<Intent> allSticky = null;
16828        if (stickyIntents != null) {
16829            final ContentResolver resolver = mContext.getContentResolver();
16830            // Look for any matching sticky broadcasts...
16831            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16832                Intent intent = stickyIntents.get(i);
16833                // If intent has scheme "content", it will need to acccess
16834                // provider that needs to lock mProviderMap in ActivityThread
16835                // and also it may need to wait application response, so we
16836                // cannot lock ActivityManagerService here.
16837                if (filter.match(resolver, intent, true, TAG) >= 0) {
16838                    if (allSticky == null) {
16839                        allSticky = new ArrayList<Intent>();
16840                    }
16841                    allSticky.add(intent);
16842                }
16843            }
16844        }
16845
16846        // The first sticky in the list is returned directly back to the client.
16847        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16848        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16849        if (receiver == null) {
16850            return sticky;
16851        }
16852
16853        synchronized (this) {
16854            if (callerApp != null && (callerApp.thread == null
16855                    || callerApp.thread.asBinder() != caller.asBinder())) {
16856                // Original caller already died
16857                return null;
16858            }
16859            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16860            if (rl == null) {
16861                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16862                        userId, receiver);
16863                if (rl.app != null) {
16864                    rl.app.receivers.add(rl);
16865                } else {
16866                    try {
16867                        receiver.asBinder().linkToDeath(rl, 0);
16868                    } catch (RemoteException e) {
16869                        return sticky;
16870                    }
16871                    rl.linkedToDeath = true;
16872                }
16873                mRegisteredReceivers.put(receiver.asBinder(), rl);
16874            } else if (rl.uid != callingUid) {
16875                throw new IllegalArgumentException(
16876                        "Receiver requested to register for uid " + callingUid
16877                        + " was previously registered for uid " + rl.uid);
16878            } else if (rl.pid != callingPid) {
16879                throw new IllegalArgumentException(
16880                        "Receiver requested to register for pid " + callingPid
16881                        + " was previously registered for pid " + rl.pid);
16882            } else if (rl.userId != userId) {
16883                throw new IllegalArgumentException(
16884                        "Receiver requested to register for user " + userId
16885                        + " was previously registered for user " + rl.userId);
16886            }
16887            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16888                    permission, callingUid, userId);
16889            rl.add(bf);
16890            if (!bf.debugCheck()) {
16891                Slog.w(TAG, "==> For Dynamic broadcast");
16892            }
16893            mReceiverResolver.addFilter(bf);
16894
16895            // Enqueue broadcasts for all existing stickies that match
16896            // this filter.
16897            if (allSticky != null) {
16898                ArrayList receivers = new ArrayList();
16899                receivers.add(bf);
16900
16901                final int stickyCount = allSticky.size();
16902                for (int i = 0; i < stickyCount; i++) {
16903                    Intent intent = allSticky.get(i);
16904                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16905                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16906                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16907                            null, 0, null, null, false, true, true, -1);
16908                    queue.enqueueParallelBroadcastLocked(r);
16909                    queue.scheduleBroadcastsLocked();
16910                }
16911            }
16912
16913            return sticky;
16914        }
16915    }
16916
16917    public void unregisterReceiver(IIntentReceiver receiver) {
16918        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16919
16920        final long origId = Binder.clearCallingIdentity();
16921        try {
16922            boolean doTrim = false;
16923
16924            synchronized(this) {
16925                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16926                if (rl != null) {
16927                    final BroadcastRecord r = rl.curBroadcast;
16928                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16929                        final boolean doNext = r.queue.finishReceiverLocked(
16930                                r, r.resultCode, r.resultData, r.resultExtras,
16931                                r.resultAbort, false);
16932                        if (doNext) {
16933                            doTrim = true;
16934                            r.queue.processNextBroadcast(false);
16935                        }
16936                    }
16937
16938                    if (rl.app != null) {
16939                        rl.app.receivers.remove(rl);
16940                    }
16941                    removeReceiverLocked(rl);
16942                    if (rl.linkedToDeath) {
16943                        rl.linkedToDeath = false;
16944                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16945                    }
16946                }
16947            }
16948
16949            // If we actually concluded any broadcasts, we might now be able
16950            // to trim the recipients' apps from our working set
16951            if (doTrim) {
16952                trimApplications();
16953                return;
16954            }
16955
16956        } finally {
16957            Binder.restoreCallingIdentity(origId);
16958        }
16959    }
16960
16961    void removeReceiverLocked(ReceiverList rl) {
16962        mRegisteredReceivers.remove(rl.receiver.asBinder());
16963        for (int i = rl.size() - 1; i >= 0; i--) {
16964            mReceiverResolver.removeFilter(rl.get(i));
16965        }
16966    }
16967
16968    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16969        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16970            ProcessRecord r = mLruProcesses.get(i);
16971            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16972                try {
16973                    r.thread.dispatchPackageBroadcast(cmd, packages);
16974                } catch (RemoteException ex) {
16975                }
16976            }
16977        }
16978    }
16979
16980    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16981            int callingUid, int[] users) {
16982        // TODO: come back and remove this assumption to triage all broadcasts
16983        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16984
16985        List<ResolveInfo> receivers = null;
16986        try {
16987            HashSet<ComponentName> singleUserReceivers = null;
16988            boolean scannedFirstReceivers = false;
16989            for (int user : users) {
16990                // Skip users that have Shell restrictions, with exception of always permitted
16991                // Shell broadcasts
16992                if (callingUid == Process.SHELL_UID
16993                        && mUserController.hasUserRestriction(
16994                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16995                        && !isPermittedShellBroadcast(intent)) {
16996                    continue;
16997                }
16998                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16999                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17000                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17001                    // If this is not the system user, we need to check for
17002                    // any receivers that should be filtered out.
17003                    for (int i=0; i<newReceivers.size(); i++) {
17004                        ResolveInfo ri = newReceivers.get(i);
17005                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17006                            newReceivers.remove(i);
17007                            i--;
17008                        }
17009                    }
17010                }
17011                if (newReceivers != null && newReceivers.size() == 0) {
17012                    newReceivers = null;
17013                }
17014                if (receivers == null) {
17015                    receivers = newReceivers;
17016                } else if (newReceivers != null) {
17017                    // We need to concatenate the additional receivers
17018                    // found with what we have do far.  This would be easy,
17019                    // but we also need to de-dup any receivers that are
17020                    // singleUser.
17021                    if (!scannedFirstReceivers) {
17022                        // Collect any single user receivers we had already retrieved.
17023                        scannedFirstReceivers = true;
17024                        for (int i=0; i<receivers.size(); i++) {
17025                            ResolveInfo ri = receivers.get(i);
17026                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17027                                ComponentName cn = new ComponentName(
17028                                        ri.activityInfo.packageName, ri.activityInfo.name);
17029                                if (singleUserReceivers == null) {
17030                                    singleUserReceivers = new HashSet<ComponentName>();
17031                                }
17032                                singleUserReceivers.add(cn);
17033                            }
17034                        }
17035                    }
17036                    // Add the new results to the existing results, tracking
17037                    // and de-dupping single user receivers.
17038                    for (int i=0; i<newReceivers.size(); i++) {
17039                        ResolveInfo ri = newReceivers.get(i);
17040                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17041                            ComponentName cn = new ComponentName(
17042                                    ri.activityInfo.packageName, ri.activityInfo.name);
17043                            if (singleUserReceivers == null) {
17044                                singleUserReceivers = new HashSet<ComponentName>();
17045                            }
17046                            if (!singleUserReceivers.contains(cn)) {
17047                                singleUserReceivers.add(cn);
17048                                receivers.add(ri);
17049                            }
17050                        } else {
17051                            receivers.add(ri);
17052                        }
17053                    }
17054                }
17055            }
17056        } catch (RemoteException ex) {
17057            // pm is in same process, this will never happen.
17058        }
17059        return receivers;
17060    }
17061
17062    private boolean isPermittedShellBroadcast(Intent intent) {
17063        // remote bugreport should always be allowed to be taken
17064        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17065    }
17066
17067    final int broadcastIntentLocked(ProcessRecord callerApp,
17068            String callerPackage, Intent intent, String resolvedType,
17069            IIntentReceiver resultTo, int resultCode, String resultData,
17070            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17071            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17072        intent = new Intent(intent);
17073
17074        // By default broadcasts do not go to stopped apps.
17075        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17076
17077        // If we have not finished booting, don't allow this to launch new processes.
17078        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17079            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17080        }
17081
17082        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17083                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17084                + " ordered=" + ordered + " userid=" + userId);
17085        if ((resultTo != null) && !ordered) {
17086            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17087        }
17088
17089        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17090                ALLOW_NON_FULL, "broadcast", callerPackage);
17091
17092        // Make sure that the user who is receiving this broadcast is running.
17093        // If not, we will just skip it. Make an exception for shutdown broadcasts
17094        // and upgrade steps.
17095
17096        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17097            if ((callingUid != Process.SYSTEM_UID
17098                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17099                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17100                Slog.w(TAG, "Skipping broadcast of " + intent
17101                        + ": user " + userId + " is stopped");
17102                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17103            }
17104        }
17105
17106        BroadcastOptions brOptions = null;
17107        if (bOptions != null) {
17108            brOptions = new BroadcastOptions(bOptions);
17109            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17110                // See if the caller is allowed to do this.  Note we are checking against
17111                // the actual real caller (not whoever provided the operation as say a
17112                // PendingIntent), because that who is actually supplied the arguments.
17113                if (checkComponentPermission(
17114                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17115                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17116                        != PackageManager.PERMISSION_GRANTED) {
17117                    String msg = "Permission Denial: " + intent.getAction()
17118                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17119                            + ", uid=" + callingUid + ")"
17120                            + " requires "
17121                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17122                    Slog.w(TAG, msg);
17123                    throw new SecurityException(msg);
17124                }
17125            }
17126        }
17127
17128        // Verify that protected broadcasts are only being sent by system code,
17129        // and that system code is only sending protected broadcasts.
17130        final String action = intent.getAction();
17131        final boolean isProtectedBroadcast;
17132        try {
17133            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17134        } catch (RemoteException e) {
17135            Slog.w(TAG, "Remote exception", e);
17136            return ActivityManager.BROADCAST_SUCCESS;
17137        }
17138
17139        final boolean isCallerSystem;
17140        switch (UserHandle.getAppId(callingUid)) {
17141            case Process.ROOT_UID:
17142            case Process.SYSTEM_UID:
17143            case Process.PHONE_UID:
17144            case Process.BLUETOOTH_UID:
17145            case Process.NFC_UID:
17146                isCallerSystem = true;
17147                break;
17148            default:
17149                isCallerSystem = (callerApp != null) && callerApp.persistent;
17150                break;
17151        }
17152
17153        if (isCallerSystem) {
17154            if (isProtectedBroadcast
17155                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17156                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17157                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17158                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17159                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17160                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17161                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17162                // Broadcast is either protected, or it's a public action that
17163                // we've relaxed, so it's fine for system internals to send.
17164            } else {
17165                // The vast majority of broadcasts sent from system internals
17166                // should be protected to avoid security holes, so yell loudly
17167                // to ensure we examine these cases.
17168                Log.wtf(TAG, "Sending non-protected broadcast " + action
17169                        + " from system", new Throwable());
17170            }
17171
17172        } else {
17173            if (isProtectedBroadcast) {
17174                String msg = "Permission Denial: not allowed to send broadcast "
17175                        + action + " from pid="
17176                        + callingPid + ", uid=" + callingUid;
17177                Slog.w(TAG, msg);
17178                throw new SecurityException(msg);
17179
17180            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17181                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17182                // Special case for compatibility: we don't want apps to send this,
17183                // but historically it has not been protected and apps may be using it
17184                // to poke their own app widget.  So, instead of making it protected,
17185                // just limit it to the caller.
17186                if (callerPackage == null) {
17187                    String msg = "Permission Denial: not allowed to send broadcast "
17188                            + action + " from unknown caller.";
17189                    Slog.w(TAG, msg);
17190                    throw new SecurityException(msg);
17191                } else if (intent.getComponent() != null) {
17192                    // They are good enough to send to an explicit component...  verify
17193                    // it is being sent to the calling app.
17194                    if (!intent.getComponent().getPackageName().equals(
17195                            callerPackage)) {
17196                        String msg = "Permission Denial: not allowed to send broadcast "
17197                                + action + " to "
17198                                + intent.getComponent().getPackageName() + " from "
17199                                + callerPackage;
17200                        Slog.w(TAG, msg);
17201                        throw new SecurityException(msg);
17202                    }
17203                } else {
17204                    // Limit broadcast to their own package.
17205                    intent.setPackage(callerPackage);
17206                }
17207            }
17208        }
17209
17210        if (action != null) {
17211            switch (action) {
17212                case Intent.ACTION_UID_REMOVED:
17213                case Intent.ACTION_PACKAGE_REMOVED:
17214                case Intent.ACTION_PACKAGE_CHANGED:
17215                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17216                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17217                case Intent.ACTION_PACKAGES_SUSPENDED:
17218                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17219                    // Handle special intents: if this broadcast is from the package
17220                    // manager about a package being removed, we need to remove all of
17221                    // its activities from the history stack.
17222                    if (checkComponentPermission(
17223                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17224                            callingPid, callingUid, -1, true)
17225                            != PackageManager.PERMISSION_GRANTED) {
17226                        String msg = "Permission Denial: " + intent.getAction()
17227                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17228                                + ", uid=" + callingUid + ")"
17229                                + " requires "
17230                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17231                        Slog.w(TAG, msg);
17232                        throw new SecurityException(msg);
17233                    }
17234                    switch (action) {
17235                        case Intent.ACTION_UID_REMOVED:
17236                            final Bundle intentExtras = intent.getExtras();
17237                            final int uid = intentExtras != null
17238                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17239                            if (uid >= 0) {
17240                                mBatteryStatsService.removeUid(uid);
17241                                mAppOpsService.uidRemoved(uid);
17242                            }
17243                            break;
17244                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17245                            // If resources are unavailable just force stop all those packages
17246                            // and flush the attribute cache as well.
17247                            String list[] =
17248                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17249                            if (list != null && list.length > 0) {
17250                                for (int i = 0; i < list.length; i++) {
17251                                    forceStopPackageLocked(list[i], -1, false, true, true,
17252                                            false, false, userId, "storage unmount");
17253                                }
17254                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17255                                sendPackageBroadcastLocked(
17256                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17257                                        userId);
17258                            }
17259                            break;
17260                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17261                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17262                            break;
17263                        case Intent.ACTION_PACKAGE_REMOVED:
17264                        case Intent.ACTION_PACKAGE_CHANGED:
17265                            Uri data = intent.getData();
17266                            String ssp;
17267                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17268                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17269                                final boolean replacing =
17270                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17271                                final boolean killProcess =
17272                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17273                                final boolean fullUninstall = removed && !replacing;
17274                                if (killProcess) {
17275                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17276                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17277                                            false, true, true, false, fullUninstall, userId,
17278                                            removed ? "pkg removed" : "pkg changed");
17279                                }
17280                                if (removed) {
17281                                    final int cmd = killProcess
17282                                            ? IApplicationThread.PACKAGE_REMOVED
17283                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17284                                    sendPackageBroadcastLocked(cmd,
17285                                            new String[] {ssp}, userId);
17286                                    if (fullUninstall) {
17287                                        mAppOpsService.packageRemoved(
17288                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17289
17290                                        // Remove all permissions granted from/to this package
17291                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17292
17293                                        removeTasksByPackageNameLocked(ssp, userId);
17294                                        mBatteryStatsService.notePackageUninstalled(ssp);
17295                                    }
17296                                } else {
17297                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17298                                            intent.getStringArrayExtra(
17299                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17300                                }
17301                            }
17302                            break;
17303                        case Intent.ACTION_PACKAGES_SUSPENDED:
17304                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17305                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17306                                    intent.getAction());
17307                            final String[] packageNames = intent.getStringArrayExtra(
17308                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17309                            final int userHandle = intent.getIntExtra(
17310                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17311
17312                            synchronized(ActivityManagerService.this) {
17313                                mRecentTasks.onPackagesSuspendedChanged(
17314                                        packageNames, suspended, userHandle);
17315                            }
17316                            break;
17317                    }
17318                    break;
17319                case Intent.ACTION_PACKAGE_REPLACED:
17320                {
17321                    final Uri data = intent.getData();
17322                    final String ssp;
17323                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17324                        final ApplicationInfo aInfo =
17325                                getPackageManagerInternalLocked().getApplicationInfo(
17326                                        ssp,
17327                                        userId);
17328                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17329                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17330                                new String[] {ssp}, userId);
17331                    }
17332                    break;
17333                }
17334                case Intent.ACTION_PACKAGE_ADDED:
17335                {
17336                    // Special case for adding a package: by default turn on compatibility mode.
17337                    Uri data = intent.getData();
17338                    String ssp;
17339                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17340                        final boolean replacing =
17341                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17342                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17343
17344                        try {
17345                            ApplicationInfo ai = AppGlobals.getPackageManager().
17346                                    getApplicationInfo(ssp, 0, 0);
17347                            mBatteryStatsService.notePackageInstalled(ssp,
17348                                    ai != null ? ai.versionCode : 0);
17349                        } catch (RemoteException e) {
17350                        }
17351                    }
17352                    break;
17353                }
17354                case Intent.ACTION_TIMEZONE_CHANGED:
17355                    // If this is the time zone changed action, queue up a message that will reset
17356                    // the timezone of all currently running processes. This message will get
17357                    // queued up before the broadcast happens.
17358                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17359                    break;
17360                case Intent.ACTION_TIME_CHANGED:
17361                    // If the user set the time, let all running processes know.
17362                    final int is24Hour =
17363                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17364                                    : 0;
17365                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17366                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17367                    synchronized (stats) {
17368                        stats.noteCurrentTimeChangedLocked();
17369                    }
17370                    break;
17371                case Intent.ACTION_CLEAR_DNS_CACHE:
17372                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17373                    break;
17374                case Proxy.PROXY_CHANGE_ACTION:
17375                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17376                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17377                    break;
17378                case android.hardware.Camera.ACTION_NEW_PICTURE:
17379                case android.hardware.Camera.ACTION_NEW_VIDEO:
17380                    // These broadcasts are no longer allowed by the system, since they can
17381                    // cause significant thrashing at a crictical point (using the camera).
17382                    // Apps should use JobScehduler to monitor for media provider changes.
17383                    Slog.w(TAG, action + " no longer allowed; dropping from "
17384                            + UserHandle.formatUid(callingUid));
17385                    // Lie; we don't want to crash the app.
17386                    return ActivityManager.BROADCAST_SUCCESS;
17387            }
17388        }
17389
17390        // Add to the sticky list if requested.
17391        if (sticky) {
17392            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17393                    callingPid, callingUid)
17394                    != PackageManager.PERMISSION_GRANTED) {
17395                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17396                        + callingPid + ", uid=" + callingUid
17397                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17398                Slog.w(TAG, msg);
17399                throw new SecurityException(msg);
17400            }
17401            if (requiredPermissions != null && requiredPermissions.length > 0) {
17402                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17403                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17404                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17405            }
17406            if (intent.getComponent() != null) {
17407                throw new SecurityException(
17408                        "Sticky broadcasts can't target a specific component");
17409            }
17410            // We use userId directly here, since the "all" target is maintained
17411            // as a separate set of sticky broadcasts.
17412            if (userId != UserHandle.USER_ALL) {
17413                // But first, if this is not a broadcast to all users, then
17414                // make sure it doesn't conflict with an existing broadcast to
17415                // all users.
17416                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17417                        UserHandle.USER_ALL);
17418                if (stickies != null) {
17419                    ArrayList<Intent> list = stickies.get(intent.getAction());
17420                    if (list != null) {
17421                        int N = list.size();
17422                        int i;
17423                        for (i=0; i<N; i++) {
17424                            if (intent.filterEquals(list.get(i))) {
17425                                throw new IllegalArgumentException(
17426                                        "Sticky broadcast " + intent + " for user "
17427                                        + userId + " conflicts with existing global broadcast");
17428                            }
17429                        }
17430                    }
17431                }
17432            }
17433            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17434            if (stickies == null) {
17435                stickies = new ArrayMap<>();
17436                mStickyBroadcasts.put(userId, stickies);
17437            }
17438            ArrayList<Intent> list = stickies.get(intent.getAction());
17439            if (list == null) {
17440                list = new ArrayList<>();
17441                stickies.put(intent.getAction(), list);
17442            }
17443            final int stickiesCount = list.size();
17444            int i;
17445            for (i = 0; i < stickiesCount; i++) {
17446                if (intent.filterEquals(list.get(i))) {
17447                    // This sticky already exists, replace it.
17448                    list.set(i, new Intent(intent));
17449                    break;
17450                }
17451            }
17452            if (i >= stickiesCount) {
17453                list.add(new Intent(intent));
17454            }
17455        }
17456
17457        int[] users;
17458        if (userId == UserHandle.USER_ALL) {
17459            // Caller wants broadcast to go to all started users.
17460            users = mUserController.getStartedUserArrayLocked();
17461        } else {
17462            // Caller wants broadcast to go to one specific user.
17463            users = new int[] {userId};
17464        }
17465
17466        // Figure out who all will receive this broadcast.
17467        List receivers = null;
17468        List<BroadcastFilter> registeredReceivers = null;
17469        // Need to resolve the intent to interested receivers...
17470        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17471                 == 0) {
17472            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17473        }
17474        if (intent.getComponent() == null) {
17475            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17476                // Query one target user at a time, excluding shell-restricted users
17477                for (int i = 0; i < users.length; i++) {
17478                    if (mUserController.hasUserRestriction(
17479                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17480                        continue;
17481                    }
17482                    List<BroadcastFilter> registeredReceiversForUser =
17483                            mReceiverResolver.queryIntent(intent,
17484                                    resolvedType, false, users[i]);
17485                    if (registeredReceivers == null) {
17486                        registeredReceivers = registeredReceiversForUser;
17487                    } else if (registeredReceiversForUser != null) {
17488                        registeredReceivers.addAll(registeredReceiversForUser);
17489                    }
17490                }
17491            } else {
17492                registeredReceivers = mReceiverResolver.queryIntent(intent,
17493                        resolvedType, false, userId);
17494            }
17495        }
17496
17497        final boolean replacePending =
17498                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17499
17500        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17501                + " replacePending=" + replacePending);
17502
17503        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17504        if (!ordered && NR > 0) {
17505            // If we are not serializing this broadcast, then send the
17506            // registered receivers separately so they don't wait for the
17507            // components to be launched.
17508            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17509            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17510                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17511                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17512                    resultExtras, ordered, sticky, false, userId);
17513            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17514            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17515            if (!replaced) {
17516                queue.enqueueParallelBroadcastLocked(r);
17517                queue.scheduleBroadcastsLocked();
17518            }
17519            registeredReceivers = null;
17520            NR = 0;
17521        }
17522
17523        // Merge into one list.
17524        int ir = 0;
17525        if (receivers != null) {
17526            // A special case for PACKAGE_ADDED: do not allow the package
17527            // being added to see this broadcast.  This prevents them from
17528            // using this as a back door to get run as soon as they are
17529            // installed.  Maybe in the future we want to have a special install
17530            // broadcast or such for apps, but we'd like to deliberately make
17531            // this decision.
17532            String skipPackages[] = null;
17533            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17534                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17535                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17536                Uri data = intent.getData();
17537                if (data != null) {
17538                    String pkgName = data.getSchemeSpecificPart();
17539                    if (pkgName != null) {
17540                        skipPackages = new String[] { pkgName };
17541                    }
17542                }
17543            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17544                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17545            }
17546            if (skipPackages != null && (skipPackages.length > 0)) {
17547                for (String skipPackage : skipPackages) {
17548                    if (skipPackage != null) {
17549                        int NT = receivers.size();
17550                        for (int it=0; it<NT; it++) {
17551                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17552                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17553                                receivers.remove(it);
17554                                it--;
17555                                NT--;
17556                            }
17557                        }
17558                    }
17559                }
17560            }
17561
17562            int NT = receivers != null ? receivers.size() : 0;
17563            int it = 0;
17564            ResolveInfo curt = null;
17565            BroadcastFilter curr = null;
17566            while (it < NT && ir < NR) {
17567                if (curt == null) {
17568                    curt = (ResolveInfo)receivers.get(it);
17569                }
17570                if (curr == null) {
17571                    curr = registeredReceivers.get(ir);
17572                }
17573                if (curr.getPriority() >= curt.priority) {
17574                    // Insert this broadcast record into the final list.
17575                    receivers.add(it, curr);
17576                    ir++;
17577                    curr = null;
17578                    it++;
17579                    NT++;
17580                } else {
17581                    // Skip to the next ResolveInfo in the final list.
17582                    it++;
17583                    curt = null;
17584                }
17585            }
17586        }
17587        while (ir < NR) {
17588            if (receivers == null) {
17589                receivers = new ArrayList();
17590            }
17591            receivers.add(registeredReceivers.get(ir));
17592            ir++;
17593        }
17594
17595        if ((receivers != null && receivers.size() > 0)
17596                || resultTo != null) {
17597            BroadcastQueue queue = broadcastQueueForIntent(intent);
17598            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17599                    callerPackage, callingPid, callingUid, resolvedType,
17600                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17601                    resultData, resultExtras, ordered, sticky, false, userId);
17602
17603            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17604                    + ": prev had " + queue.mOrderedBroadcasts.size());
17605            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17606                    "Enqueueing broadcast " + r.intent.getAction());
17607
17608            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17609            if (!replaced) {
17610                queue.enqueueOrderedBroadcastLocked(r);
17611                queue.scheduleBroadcastsLocked();
17612            }
17613        }
17614
17615        return ActivityManager.BROADCAST_SUCCESS;
17616    }
17617
17618    final Intent verifyBroadcastLocked(Intent intent) {
17619        // Refuse possible leaked file descriptors
17620        if (intent != null && intent.hasFileDescriptors() == true) {
17621            throw new IllegalArgumentException("File descriptors passed in Intent");
17622        }
17623
17624        int flags = intent.getFlags();
17625
17626        if (!mProcessesReady) {
17627            // if the caller really truly claims to know what they're doing, go
17628            // ahead and allow the broadcast without launching any receivers
17629            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17630                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17631            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17632                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17633                        + " before boot completion");
17634                throw new IllegalStateException("Cannot broadcast before boot completed");
17635            }
17636        }
17637
17638        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17639            throw new IllegalArgumentException(
17640                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17641        }
17642
17643        return intent;
17644    }
17645
17646    public final int broadcastIntent(IApplicationThread caller,
17647            Intent intent, String resolvedType, IIntentReceiver resultTo,
17648            int resultCode, String resultData, Bundle resultExtras,
17649            String[] requiredPermissions, int appOp, Bundle bOptions,
17650            boolean serialized, boolean sticky, int userId) {
17651        enforceNotIsolatedCaller("broadcastIntent");
17652        synchronized(this) {
17653            intent = verifyBroadcastLocked(intent);
17654
17655            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17656            final int callingPid = Binder.getCallingPid();
17657            final int callingUid = Binder.getCallingUid();
17658            final long origId = Binder.clearCallingIdentity();
17659            int res = broadcastIntentLocked(callerApp,
17660                    callerApp != null ? callerApp.info.packageName : null,
17661                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17662                    requiredPermissions, appOp, bOptions, serialized, sticky,
17663                    callingPid, callingUid, userId);
17664            Binder.restoreCallingIdentity(origId);
17665            return res;
17666        }
17667    }
17668
17669
17670    int broadcastIntentInPackage(String packageName, int uid,
17671            Intent intent, String resolvedType, IIntentReceiver resultTo,
17672            int resultCode, String resultData, Bundle resultExtras,
17673            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17674            int userId) {
17675        synchronized(this) {
17676            intent = verifyBroadcastLocked(intent);
17677
17678            final long origId = Binder.clearCallingIdentity();
17679            String[] requiredPermissions = requiredPermission == null ? null
17680                    : new String[] {requiredPermission};
17681            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17682                    resultTo, resultCode, resultData, resultExtras,
17683                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17684                    sticky, -1, uid, userId);
17685            Binder.restoreCallingIdentity(origId);
17686            return res;
17687        }
17688    }
17689
17690    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17691        // Refuse possible leaked file descriptors
17692        if (intent != null && intent.hasFileDescriptors() == true) {
17693            throw new IllegalArgumentException("File descriptors passed in Intent");
17694        }
17695
17696        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17697                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17698
17699        synchronized(this) {
17700            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17701                    != PackageManager.PERMISSION_GRANTED) {
17702                String msg = "Permission Denial: unbroadcastIntent() from pid="
17703                        + Binder.getCallingPid()
17704                        + ", uid=" + Binder.getCallingUid()
17705                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17706                Slog.w(TAG, msg);
17707                throw new SecurityException(msg);
17708            }
17709            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17710            if (stickies != null) {
17711                ArrayList<Intent> list = stickies.get(intent.getAction());
17712                if (list != null) {
17713                    int N = list.size();
17714                    int i;
17715                    for (i=0; i<N; i++) {
17716                        if (intent.filterEquals(list.get(i))) {
17717                            list.remove(i);
17718                            break;
17719                        }
17720                    }
17721                    if (list.size() <= 0) {
17722                        stickies.remove(intent.getAction());
17723                    }
17724                }
17725                if (stickies.size() <= 0) {
17726                    mStickyBroadcasts.remove(userId);
17727                }
17728            }
17729        }
17730    }
17731
17732    void backgroundServicesFinishedLocked(int userId) {
17733        for (BroadcastQueue queue : mBroadcastQueues) {
17734            queue.backgroundServicesFinishedLocked(userId);
17735        }
17736    }
17737
17738    public void finishReceiver(IBinder who, int resultCode, String resultData,
17739            Bundle resultExtras, boolean resultAbort, int flags) {
17740        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17741
17742        // Refuse possible leaked file descriptors
17743        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17744            throw new IllegalArgumentException("File descriptors passed in Bundle");
17745        }
17746
17747        final long origId = Binder.clearCallingIdentity();
17748        try {
17749            boolean doNext = false;
17750            BroadcastRecord r;
17751
17752            synchronized(this) {
17753                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17754                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17755                r = queue.getMatchingOrderedReceiver(who);
17756                if (r != null) {
17757                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17758                        resultData, resultExtras, resultAbort, true);
17759                }
17760            }
17761
17762            if (doNext) {
17763                r.queue.processNextBroadcast(false);
17764            }
17765            trimApplications();
17766        } finally {
17767            Binder.restoreCallingIdentity(origId);
17768        }
17769    }
17770
17771    // =========================================================
17772    // INSTRUMENTATION
17773    // =========================================================
17774
17775    public boolean startInstrumentation(ComponentName className,
17776            String profileFile, int flags, Bundle arguments,
17777            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17778            int userId, String abiOverride) {
17779        enforceNotIsolatedCaller("startInstrumentation");
17780        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17781                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17782        // Refuse possible leaked file descriptors
17783        if (arguments != null && arguments.hasFileDescriptors()) {
17784            throw new IllegalArgumentException("File descriptors passed in Bundle");
17785        }
17786
17787        synchronized(this) {
17788            InstrumentationInfo ii = null;
17789            ApplicationInfo ai = null;
17790            try {
17791                ii = mContext.getPackageManager().getInstrumentationInfo(
17792                    className, STOCK_PM_FLAGS);
17793                ai = AppGlobals.getPackageManager().getApplicationInfo(
17794                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17795            } catch (PackageManager.NameNotFoundException e) {
17796            } catch (RemoteException e) {
17797            }
17798            if (ii == null) {
17799                reportStartInstrumentationFailureLocked(watcher, className,
17800                        "Unable to find instrumentation info for: " + className);
17801                return false;
17802            }
17803            if (ai == null) {
17804                reportStartInstrumentationFailureLocked(watcher, className,
17805                        "Unable to find instrumentation target package: " + ii.targetPackage);
17806                return false;
17807            }
17808            if (!ai.hasCode()) {
17809                reportStartInstrumentationFailureLocked(watcher, className,
17810                        "Instrumentation target has no code: " + ii.targetPackage);
17811                return false;
17812            }
17813
17814            int match = mContext.getPackageManager().checkSignatures(
17815                    ii.targetPackage, ii.packageName);
17816            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17817                String msg = "Permission Denial: starting instrumentation "
17818                        + className + " from pid="
17819                        + Binder.getCallingPid()
17820                        + ", uid=" + Binder.getCallingPid()
17821                        + " not allowed because package " + ii.packageName
17822                        + " does not have a signature matching the target "
17823                        + ii.targetPackage;
17824                reportStartInstrumentationFailureLocked(watcher, className, msg);
17825                throw new SecurityException(msg);
17826            }
17827
17828            final long origId = Binder.clearCallingIdentity();
17829            // Instrumentation can kill and relaunch even persistent processes
17830            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17831                    "start instr");
17832            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17833            app.instrumentationClass = className;
17834            app.instrumentationInfo = ai;
17835            app.instrumentationProfileFile = profileFile;
17836            app.instrumentationArguments = arguments;
17837            app.instrumentationWatcher = watcher;
17838            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17839            app.instrumentationResultClass = className;
17840            Binder.restoreCallingIdentity(origId);
17841        }
17842
17843        return true;
17844    }
17845
17846    /**
17847     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17848     * error to the logs, but if somebody is watching, send the report there too.  This enables
17849     * the "am" command to report errors with more information.
17850     *
17851     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17852     * @param cn The component name of the instrumentation.
17853     * @param report The error report.
17854     */
17855    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17856            ComponentName cn, String report) {
17857        Slog.w(TAG, report);
17858        if (watcher != null) {
17859            Bundle results = new Bundle();
17860            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17861            results.putString("Error", report);
17862            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17863        }
17864    }
17865
17866    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17867        if (app.instrumentationWatcher != null) {
17868            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17869                    app.instrumentationClass, resultCode, results);
17870        }
17871
17872        // Can't call out of the system process with a lock held, so post a message.
17873        if (app.instrumentationUiAutomationConnection != null) {
17874            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17875                    app.instrumentationUiAutomationConnection).sendToTarget();
17876        }
17877
17878        app.instrumentationWatcher = null;
17879        app.instrumentationUiAutomationConnection = null;
17880        app.instrumentationClass = null;
17881        app.instrumentationInfo = null;
17882        app.instrumentationProfileFile = null;
17883        app.instrumentationArguments = null;
17884
17885        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17886                "finished inst");
17887    }
17888
17889    public void finishInstrumentation(IApplicationThread target,
17890            int resultCode, Bundle results) {
17891        int userId = UserHandle.getCallingUserId();
17892        // Refuse possible leaked file descriptors
17893        if (results != null && results.hasFileDescriptors()) {
17894            throw new IllegalArgumentException("File descriptors passed in Intent");
17895        }
17896
17897        synchronized(this) {
17898            ProcessRecord app = getRecordForAppLocked(target);
17899            if (app == null) {
17900                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17901                return;
17902            }
17903            final long origId = Binder.clearCallingIdentity();
17904            finishInstrumentationLocked(app, resultCode, results);
17905            Binder.restoreCallingIdentity(origId);
17906        }
17907    }
17908
17909    // =========================================================
17910    // CONFIGURATION
17911    // =========================================================
17912
17913    public ConfigurationInfo getDeviceConfigurationInfo() {
17914        ConfigurationInfo config = new ConfigurationInfo();
17915        synchronized (this) {
17916            config.reqTouchScreen = mConfiguration.touchscreen;
17917            config.reqKeyboardType = mConfiguration.keyboard;
17918            config.reqNavigation = mConfiguration.navigation;
17919            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17920                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17921                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17922            }
17923            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17924                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17925                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17926            }
17927            config.reqGlEsVersion = GL_ES_VERSION;
17928        }
17929        return config;
17930    }
17931
17932    ActivityStack getFocusedStack() {
17933        return mStackSupervisor.getFocusedStack();
17934    }
17935
17936    @Override
17937    public int getFocusedStackId() throws RemoteException {
17938        ActivityStack focusedStack = getFocusedStack();
17939        if (focusedStack != null) {
17940            return focusedStack.getStackId();
17941        }
17942        return -1;
17943    }
17944
17945    public Configuration getConfiguration() {
17946        Configuration ci;
17947        synchronized(this) {
17948            ci = new Configuration(mConfiguration);
17949            ci.userSetLocale = false;
17950        }
17951        return ci;
17952    }
17953
17954    @Override
17955    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17956        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17957        synchronized (this) {
17958            mSuppressResizeConfigChanges = suppress;
17959        }
17960    }
17961
17962    @Override
17963    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17964        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17965        if (fromStackId == HOME_STACK_ID) {
17966            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17967        }
17968        synchronized (this) {
17969            final long origId = Binder.clearCallingIdentity();
17970            try {
17971                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
17972            } finally {
17973                Binder.restoreCallingIdentity(origId);
17974            }
17975        }
17976    }
17977
17978    @Override
17979    public void updatePersistentConfiguration(Configuration values) {
17980        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17981                "updateConfiguration()");
17982        enforceWriteSettingsPermission("updateConfiguration()");
17983        if (values == null) {
17984            throw new NullPointerException("Configuration must not be null");
17985        }
17986
17987        int userId = UserHandle.getCallingUserId();
17988
17989        synchronized(this) {
17990            final long origId = Binder.clearCallingIdentity();
17991            updateConfigurationLocked(values, null, false, true, userId);
17992            Binder.restoreCallingIdentity(origId);
17993        }
17994    }
17995
17996    private void updateFontScaleIfNeeded() {
17997        final int currentUserId;
17998        synchronized(this) {
17999            currentUserId = mUserController.getCurrentUserIdLocked();
18000        }
18001        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18002                FONT_SCALE, 1.0f, currentUserId);
18003        if (mConfiguration.fontScale != scaleFactor) {
18004            final Configuration configuration = mWindowManager.computeNewConfiguration();
18005            configuration.fontScale = scaleFactor;
18006            updatePersistentConfiguration(configuration);
18007        }
18008    }
18009
18010    private void enforceWriteSettingsPermission(String func) {
18011        int uid = Binder.getCallingUid();
18012        if (uid == Process.ROOT_UID) {
18013            return;
18014        }
18015
18016        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18017                Settings.getPackageNameForUid(mContext, uid), false)) {
18018            return;
18019        }
18020
18021        String msg = "Permission Denial: " + func + " from pid="
18022                + Binder.getCallingPid()
18023                + ", uid=" + uid
18024                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18025        Slog.w(TAG, msg);
18026        throw new SecurityException(msg);
18027    }
18028
18029    public void updateConfiguration(Configuration values) {
18030        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18031                "updateConfiguration()");
18032
18033        synchronized(this) {
18034            if (values == null && mWindowManager != null) {
18035                // sentinel: fetch the current configuration from the window manager
18036                values = mWindowManager.computeNewConfiguration();
18037            }
18038
18039            if (mWindowManager != null) {
18040                mProcessList.applyDisplaySize(mWindowManager);
18041            }
18042
18043            final long origId = Binder.clearCallingIdentity();
18044            if (values != null) {
18045                Settings.System.clearConfiguration(values);
18046            }
18047            updateConfigurationLocked(values, null, false);
18048            Binder.restoreCallingIdentity(origId);
18049        }
18050    }
18051
18052    void updateUserConfigurationLocked() {
18053        Configuration configuration = new Configuration(mConfiguration);
18054        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18055                mUserController.getCurrentUserIdLocked());
18056        updateConfigurationLocked(configuration, null, false);
18057    }
18058
18059    boolean updateConfigurationLocked(Configuration values,
18060            ActivityRecord starting, boolean initLocale) {
18061        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18062        return updateConfigurationLocked(values, starting, initLocale, false,
18063                UserHandle.USER_NULL);
18064    }
18065
18066    // To cache the list of supported system locales
18067    private String[] mSupportedSystemLocales = null;
18068
18069    /**
18070     * Do either or both things: (1) change the current configuration, and (2)
18071     * make sure the given activity is running with the (now) current
18072     * configuration.  Returns true if the activity has been left running, or
18073     * false if <var>starting</var> is being destroyed to match the new
18074     * configuration.
18075     *
18076     * @param userId is only used when persistent parameter is set to true to persist configuration
18077     *               for that particular user
18078     */
18079    private boolean updateConfigurationLocked(Configuration values,
18080            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18081        int changes = 0;
18082
18083        if (mWindowManager != null) {
18084            mWindowManager.deferSurfaceLayout();
18085        }
18086        if (values != null) {
18087            Configuration newConfig = new Configuration(mConfiguration);
18088            changes = newConfig.updateFrom(values);
18089            if (changes != 0) {
18090                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18091                        "Updating configuration to: " + values);
18092
18093                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18094
18095                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18096                    final Locale locale;
18097                    if (values.getLocales().size() == 1) {
18098                        // This is an optimization to avoid the JNI call when the result of
18099                        // getFirstMatch() does not depend on the supported locales.
18100                        locale = values.getLocales().get(0);
18101                    } else {
18102                        if (mSupportedSystemLocales == null) {
18103                            mSupportedSystemLocales =
18104                                    Resources.getSystem().getAssets().getLocales();
18105                        }
18106                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18107                    }
18108                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18109                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18110                            locale));
18111                }
18112
18113                mConfigurationSeq++;
18114                if (mConfigurationSeq <= 0) {
18115                    mConfigurationSeq = 1;
18116                }
18117                newConfig.seq = mConfigurationSeq;
18118                mConfiguration = newConfig;
18119                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18120                mUsageStatsService.reportConfigurationChange(newConfig,
18121                        mUserController.getCurrentUserIdLocked());
18122                //mUsageStatsService.noteStartConfig(newConfig);
18123
18124                final Configuration configCopy = new Configuration(mConfiguration);
18125
18126                // TODO: If our config changes, should we auto dismiss any currently
18127                // showing dialogs?
18128                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18129
18130                AttributeCache ac = AttributeCache.instance();
18131                if (ac != null) {
18132                    ac.updateConfiguration(configCopy);
18133                }
18134
18135                // Make sure all resources in our process are updated
18136                // right now, so that anyone who is going to retrieve
18137                // resource values after we return will be sure to get
18138                // the new ones.  This is especially important during
18139                // boot, where the first config change needs to guarantee
18140                // all resources have that config before following boot
18141                // code is executed.
18142                mSystemThread.applyConfigurationToResources(configCopy);
18143
18144                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18145                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18146                    msg.obj = new Configuration(configCopy);
18147                    msg.arg1 = userId;
18148                    mHandler.sendMessage(msg);
18149                }
18150
18151                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18152                if (isDensityChange) {
18153                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18154                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18155                }
18156
18157                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18158                    ProcessRecord app = mLruProcesses.get(i);
18159                    try {
18160                        if (app.thread != null) {
18161                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18162                                    + app.processName + " new config " + mConfiguration);
18163                            app.thread.scheduleConfigurationChanged(configCopy);
18164                        }
18165                    } catch (Exception e) {
18166                    }
18167                }
18168                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18169                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18170                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18171                        | Intent.FLAG_RECEIVER_FOREGROUND);
18172                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18173                        null, AppOpsManager.OP_NONE, null, false, false,
18174                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18175                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18176                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18177                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18178                    if (!mProcessesReady) {
18179                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18180                    }
18181                    broadcastIntentLocked(null, null, intent,
18182                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18183                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18184                }
18185            }
18186            // Update the configuration with WM first and check if any of the stacks need to be
18187            // resized due to the configuration change. If so, resize the stacks now and do any
18188            // relaunches if necessary. This way we don't need to relaunch again below in
18189            // ensureActivityConfigurationLocked().
18190            if (mWindowManager != null) {
18191                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18192                if (resizedStacks != null) {
18193                    for (int stackId : resizedStacks) {
18194                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18195                        mStackSupervisor.resizeStackLocked(
18196                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18197                    }
18198                }
18199            }
18200        }
18201
18202        boolean kept = true;
18203        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18204        // mainStack is null during startup.
18205        if (mainStack != null) {
18206            if (changes != 0 && starting == null) {
18207                // If the configuration changed, and the caller is not already
18208                // in the process of starting an activity, then find the top
18209                // activity to check if its configuration needs to change.
18210                starting = mainStack.topRunningActivityLocked();
18211            }
18212
18213            if (starting != null) {
18214                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18215                // And we need to make sure at this point that all other activities
18216                // are made visible with the correct configuration.
18217                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18218                        !PRESERVE_WINDOWS);
18219            }
18220        }
18221        if (mWindowManager != null) {
18222            mWindowManager.continueSurfaceLayout();
18223        }
18224        return kept;
18225    }
18226
18227    /**
18228     * Decide based on the configuration whether we should shouw the ANR,
18229     * crash, etc dialogs.  The idea is that if there is no affordnace to
18230     * press the on-screen buttons, we shouldn't show the dialog.
18231     *
18232     * A thought: SystemUI might also want to get told about this, the Power
18233     * dialog / global actions also might want different behaviors.
18234     */
18235    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18236        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18237                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18238                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18239        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18240                                    == Configuration.UI_MODE_TYPE_CAR);
18241        return inputMethodExists && uiIsNotCarType && !inVrMode;
18242    }
18243
18244    @Override
18245    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18246        synchronized (this) {
18247            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18248            if (srec != null) {
18249                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18250            }
18251        }
18252        return false;
18253    }
18254
18255    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18256            Intent resultData) {
18257
18258        synchronized (this) {
18259            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18260            if (r != null) {
18261                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18262            }
18263            return false;
18264        }
18265    }
18266
18267    public int getLaunchedFromUid(IBinder activityToken) {
18268        ActivityRecord srec;
18269        synchronized (this) {
18270            srec = ActivityRecord.forTokenLocked(activityToken);
18271        }
18272        if (srec == null) {
18273            return -1;
18274        }
18275        return srec.launchedFromUid;
18276    }
18277
18278    public String getLaunchedFromPackage(IBinder activityToken) {
18279        ActivityRecord srec;
18280        synchronized (this) {
18281            srec = ActivityRecord.forTokenLocked(activityToken);
18282        }
18283        if (srec == null) {
18284            return null;
18285        }
18286        return srec.launchedFromPackage;
18287    }
18288
18289    // =========================================================
18290    // LIFETIME MANAGEMENT
18291    // =========================================================
18292
18293    // Returns which broadcast queue the app is the current [or imminent] receiver
18294    // on, or 'null' if the app is not an active broadcast recipient.
18295    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18296        BroadcastRecord r = app.curReceiver;
18297        if (r != null) {
18298            return r.queue;
18299        }
18300
18301        // It's not the current receiver, but it might be starting up to become one
18302        synchronized (this) {
18303            for (BroadcastQueue queue : mBroadcastQueues) {
18304                r = queue.mPendingBroadcast;
18305                if (r != null && r.curApp == app) {
18306                    // found it; report which queue it's in
18307                    return queue;
18308                }
18309            }
18310        }
18311
18312        return null;
18313    }
18314
18315    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18316            int targetUid, ComponentName targetComponent, String targetProcess) {
18317        if (!mTrackingAssociations) {
18318            return null;
18319        }
18320        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18321                = mAssociations.get(targetUid);
18322        if (components == null) {
18323            components = new ArrayMap<>();
18324            mAssociations.put(targetUid, components);
18325        }
18326        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18327        if (sourceUids == null) {
18328            sourceUids = new SparseArray<>();
18329            components.put(targetComponent, sourceUids);
18330        }
18331        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18332        if (sourceProcesses == null) {
18333            sourceProcesses = new ArrayMap<>();
18334            sourceUids.put(sourceUid, sourceProcesses);
18335        }
18336        Association ass = sourceProcesses.get(sourceProcess);
18337        if (ass == null) {
18338            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18339                    targetProcess);
18340            sourceProcesses.put(sourceProcess, ass);
18341        }
18342        ass.mCount++;
18343        ass.mNesting++;
18344        if (ass.mNesting == 1) {
18345            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18346            ass.mLastState = sourceState;
18347        }
18348        return ass;
18349    }
18350
18351    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18352            ComponentName targetComponent) {
18353        if (!mTrackingAssociations) {
18354            return;
18355        }
18356        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18357                = mAssociations.get(targetUid);
18358        if (components == null) {
18359            return;
18360        }
18361        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18362        if (sourceUids == null) {
18363            return;
18364        }
18365        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18366        if (sourceProcesses == null) {
18367            return;
18368        }
18369        Association ass = sourceProcesses.get(sourceProcess);
18370        if (ass == null || ass.mNesting <= 0) {
18371            return;
18372        }
18373        ass.mNesting--;
18374        if (ass.mNesting == 0) {
18375            long uptime = SystemClock.uptimeMillis();
18376            ass.mTime += uptime - ass.mStartTime;
18377            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18378                    += uptime - ass.mLastStateUptime;
18379            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18380        }
18381    }
18382
18383    private void noteUidProcessState(final int uid, final int state) {
18384        mBatteryStatsService.noteUidProcessState(uid, state);
18385        if (mTrackingAssociations) {
18386            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18387                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18388                        = mAssociations.valueAt(i1);
18389                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18390                    SparseArray<ArrayMap<String, Association>> sourceUids
18391                            = targetComponents.valueAt(i2);
18392                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18393                    if (sourceProcesses != null) {
18394                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18395                            Association ass = sourceProcesses.valueAt(i4);
18396                            if (ass.mNesting >= 1) {
18397                                // currently associated
18398                                long uptime = SystemClock.uptimeMillis();
18399                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18400                                        += uptime - ass.mLastStateUptime;
18401                                ass.mLastState = state;
18402                                ass.mLastStateUptime = uptime;
18403                            }
18404                        }
18405                    }
18406                }
18407            }
18408        }
18409    }
18410
18411    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18412            boolean doingAll, long now) {
18413        if (mAdjSeq == app.adjSeq) {
18414            // This adjustment has already been computed.
18415            return app.curRawAdj;
18416        }
18417
18418        if (app.thread == null) {
18419            app.adjSeq = mAdjSeq;
18420            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18421            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18422            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18423        }
18424
18425        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18426        app.adjSource = null;
18427        app.adjTarget = null;
18428        app.empty = false;
18429        app.cached = false;
18430
18431        final int activitiesSize = app.activities.size();
18432
18433        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18434            // The max adjustment doesn't allow this app to be anything
18435            // below foreground, so it is not worth doing work for it.
18436            app.adjType = "fixed";
18437            app.adjSeq = mAdjSeq;
18438            app.curRawAdj = app.maxAdj;
18439            app.foregroundActivities = false;
18440            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18441            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18442            // System processes can do UI, and when they do we want to have
18443            // them trim their memory after the user leaves the UI.  To
18444            // facilitate this, here we need to determine whether or not it
18445            // is currently showing UI.
18446            app.systemNoUi = true;
18447            if (app == TOP_APP) {
18448                app.systemNoUi = false;
18449            } else if (activitiesSize > 0) {
18450                for (int j = 0; j < activitiesSize; j++) {
18451                    final ActivityRecord r = app.activities.get(j);
18452                    if (r.visible) {
18453                        app.systemNoUi = false;
18454                    }
18455                }
18456            }
18457            if (!app.systemNoUi) {
18458                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18459            }
18460            return (app.curAdj=app.maxAdj);
18461        }
18462
18463        app.systemNoUi = false;
18464
18465        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18466
18467        // Determine the importance of the process, starting with most
18468        // important to least, and assign an appropriate OOM adjustment.
18469        int adj;
18470        int schedGroup;
18471        int procState;
18472        boolean foregroundActivities = false;
18473        BroadcastQueue queue;
18474        if (app == TOP_APP) {
18475            // The last app on the list is the foreground app.
18476            adj = ProcessList.FOREGROUND_APP_ADJ;
18477            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18478            app.adjType = "top-activity";
18479            foregroundActivities = true;
18480            procState = PROCESS_STATE_CUR_TOP;
18481        } else if (app.instrumentationClass != null) {
18482            // Don't want to kill running instrumentation.
18483            adj = ProcessList.FOREGROUND_APP_ADJ;
18484            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18485            app.adjType = "instrumentation";
18486            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18487        } else if ((queue = isReceivingBroadcast(app)) != null) {
18488            // An app that is currently receiving a broadcast also
18489            // counts as being in the foreground for OOM killer purposes.
18490            // It's placed in a sched group based on the nature of the
18491            // broadcast as reflected by which queue it's active in.
18492            adj = ProcessList.FOREGROUND_APP_ADJ;
18493            schedGroup = (queue == mFgBroadcastQueue)
18494                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18495            app.adjType = "broadcast";
18496            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18497        } else if (app.executingServices.size() > 0) {
18498            // An app that is currently executing a service callback also
18499            // counts as being in the foreground.
18500            adj = ProcessList.FOREGROUND_APP_ADJ;
18501            schedGroup = app.execServicesFg ?
18502                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18503            app.adjType = "exec-service";
18504            procState = ActivityManager.PROCESS_STATE_SERVICE;
18505            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18506        } else {
18507            // As far as we know the process is empty.  We may change our mind later.
18508            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18509            // At this point we don't actually know the adjustment.  Use the cached adj
18510            // value that the caller wants us to.
18511            adj = cachedAdj;
18512            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18513            app.cached = true;
18514            app.empty = true;
18515            app.adjType = "cch-empty";
18516        }
18517
18518        // Examine all activities if not already foreground.
18519        if (!foregroundActivities && activitiesSize > 0) {
18520            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18521            for (int j = 0; j < activitiesSize; j++) {
18522                final ActivityRecord r = app.activities.get(j);
18523                if (r.app != app) {
18524                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18525                            + " instead of expected " + app);
18526                    if (r.app == null || (r.app.uid == app.uid)) {
18527                        // Only fix things up when they look sane
18528                        r.app = app;
18529                    } else {
18530                        continue;
18531                    }
18532                }
18533                if (r.visible) {
18534                    // App has a visible activity; only upgrade adjustment.
18535                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18536                        adj = ProcessList.VISIBLE_APP_ADJ;
18537                        app.adjType = "visible";
18538                    }
18539                    if (procState > PROCESS_STATE_CUR_TOP) {
18540                        procState = PROCESS_STATE_CUR_TOP;
18541                    }
18542                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18543                    app.cached = false;
18544                    app.empty = false;
18545                    foregroundActivities = true;
18546                    if (r.task != null && minLayer > 0) {
18547                        final int layer = r.task.mLayerRank;
18548                        if (layer >= 0 && minLayer > layer) {
18549                            minLayer = layer;
18550                        }
18551                    }
18552                    break;
18553                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18554                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18555                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18556                        app.adjType = "pausing";
18557                    }
18558                    if (procState > PROCESS_STATE_CUR_TOP) {
18559                        procState = PROCESS_STATE_CUR_TOP;
18560                    }
18561                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18562                    app.cached = false;
18563                    app.empty = false;
18564                    foregroundActivities = true;
18565                } else if (r.state == ActivityState.STOPPING) {
18566                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18567                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18568                        app.adjType = "stopping";
18569                    }
18570                    // For the process state, we will at this point consider the
18571                    // process to be cached.  It will be cached either as an activity
18572                    // or empty depending on whether the activity is finishing.  We do
18573                    // this so that we can treat the process as cached for purposes of
18574                    // memory trimming (determing current memory level, trim command to
18575                    // send to process) since there can be an arbitrary number of stopping
18576                    // processes and they should soon all go into the cached state.
18577                    if (!r.finishing) {
18578                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18579                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18580                        }
18581                    }
18582                    app.cached = false;
18583                    app.empty = false;
18584                    foregroundActivities = true;
18585                } else {
18586                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18587                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18588                        app.adjType = "cch-act";
18589                    }
18590                }
18591            }
18592            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18593                adj += minLayer;
18594            }
18595        }
18596
18597        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18598                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18599            if (app.foregroundServices) {
18600                // The user is aware of this app, so make it visible.
18601                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18602                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18603                app.cached = false;
18604                app.adjType = "fg-service";
18605                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18606            } else if (app.forcingToForeground != null) {
18607                // The user is aware of this app, so make it visible.
18608                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18609                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18610                app.cached = false;
18611                app.adjType = "force-fg";
18612                app.adjSource = app.forcingToForeground;
18613                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18614            }
18615        }
18616
18617        if (app == mHeavyWeightProcess) {
18618            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18619                // We don't want to kill the current heavy-weight process.
18620                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18621                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18622                app.cached = false;
18623                app.adjType = "heavy";
18624            }
18625            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18626                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18627            }
18628        }
18629
18630        if (app == mHomeProcess) {
18631            if (adj > ProcessList.HOME_APP_ADJ) {
18632                // This process is hosting what we currently consider to be the
18633                // home app, so we don't want to let it go into the background.
18634                adj = ProcessList.HOME_APP_ADJ;
18635                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18636                app.cached = false;
18637                app.adjType = "home";
18638            }
18639            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18640                procState = ActivityManager.PROCESS_STATE_HOME;
18641            }
18642        }
18643
18644        if (app == mPreviousProcess && app.activities.size() > 0) {
18645            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18646                // This was the previous process that showed UI to the user.
18647                // We want to try to keep it around more aggressively, to give
18648                // a good experience around switching between two apps.
18649                adj = ProcessList.PREVIOUS_APP_ADJ;
18650                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18651                app.cached = false;
18652                app.adjType = "previous";
18653            }
18654            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18655                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18656            }
18657        }
18658
18659        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18660                + " reason=" + app.adjType);
18661
18662        // By default, we use the computed adjustment.  It may be changed if
18663        // there are applications dependent on our services or providers, but
18664        // this gives us a baseline and makes sure we don't get into an
18665        // infinite recursion.
18666        app.adjSeq = mAdjSeq;
18667        app.curRawAdj = adj;
18668        app.hasStartedServices = false;
18669
18670        if (mBackupTarget != null && app == mBackupTarget.app) {
18671            // If possible we want to avoid killing apps while they're being backed up
18672            if (adj > ProcessList.BACKUP_APP_ADJ) {
18673                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18674                adj = ProcessList.BACKUP_APP_ADJ;
18675                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18676                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18677                }
18678                app.adjType = "backup";
18679                app.cached = false;
18680            }
18681            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18682                procState = ActivityManager.PROCESS_STATE_BACKUP;
18683            }
18684        }
18685
18686        boolean mayBeTop = false;
18687
18688        for (int is = app.services.size()-1;
18689                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18690                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18691                        || procState > ActivityManager.PROCESS_STATE_TOP);
18692                is--) {
18693            ServiceRecord s = app.services.valueAt(is);
18694            if (s.startRequested) {
18695                app.hasStartedServices = true;
18696                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18697                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18698                }
18699                if (app.hasShownUi && app != mHomeProcess) {
18700                    // If this process has shown some UI, let it immediately
18701                    // go to the LRU list because it may be pretty heavy with
18702                    // UI stuff.  We'll tag it with a label just to help
18703                    // debug and understand what is going on.
18704                    if (adj > ProcessList.SERVICE_ADJ) {
18705                        app.adjType = "cch-started-ui-services";
18706                    }
18707                } else {
18708                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18709                        // This service has seen some activity within
18710                        // recent memory, so we will keep its process ahead
18711                        // of the background processes.
18712                        if (adj > ProcessList.SERVICE_ADJ) {
18713                            adj = ProcessList.SERVICE_ADJ;
18714                            app.adjType = "started-services";
18715                            app.cached = false;
18716                        }
18717                    }
18718                    // If we have let the service slide into the background
18719                    // state, still have some text describing what it is doing
18720                    // even though the service no longer has an impact.
18721                    if (adj > ProcessList.SERVICE_ADJ) {
18722                        app.adjType = "cch-started-services";
18723                    }
18724                }
18725            }
18726            for (int conni = s.connections.size()-1;
18727                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18728                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18729                            || procState > ActivityManager.PROCESS_STATE_TOP);
18730                    conni--) {
18731                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18732                for (int i = 0;
18733                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18734                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18735                                || procState > ActivityManager.PROCESS_STATE_TOP);
18736                        i++) {
18737                    // XXX should compute this based on the max of
18738                    // all connected clients.
18739                    ConnectionRecord cr = clist.get(i);
18740                    if (cr.binding.client == app) {
18741                        // Binding to ourself is not interesting.
18742                        continue;
18743                    }
18744                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18745                        ProcessRecord client = cr.binding.client;
18746                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18747                                TOP_APP, doingAll, now);
18748                        int clientProcState = client.curProcState;
18749                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18750                            // If the other app is cached for any reason, for purposes here
18751                            // we are going to consider it empty.  The specific cached state
18752                            // doesn't propagate except under certain conditions.
18753                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18754                        }
18755                        String adjType = null;
18756                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18757                            // Not doing bind OOM management, so treat
18758                            // this guy more like a started service.
18759                            if (app.hasShownUi && app != mHomeProcess) {
18760                                // If this process has shown some UI, let it immediately
18761                                // go to the LRU list because it may be pretty heavy with
18762                                // UI stuff.  We'll tag it with a label just to help
18763                                // debug and understand what is going on.
18764                                if (adj > clientAdj) {
18765                                    adjType = "cch-bound-ui-services";
18766                                }
18767                                app.cached = false;
18768                                clientAdj = adj;
18769                                clientProcState = procState;
18770                            } else {
18771                                if (now >= (s.lastActivity
18772                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18773                                    // This service has not seen activity within
18774                                    // recent memory, so allow it to drop to the
18775                                    // LRU list if there is no other reason to keep
18776                                    // it around.  We'll also tag it with a label just
18777                                    // to help debug and undertand what is going on.
18778                                    if (adj > clientAdj) {
18779                                        adjType = "cch-bound-services";
18780                                    }
18781                                    clientAdj = adj;
18782                                }
18783                            }
18784                        }
18785                        if (adj > clientAdj) {
18786                            // If this process has recently shown UI, and
18787                            // the process that is binding to it is less
18788                            // important than being visible, then we don't
18789                            // care about the binding as much as we care
18790                            // about letting this process get into the LRU
18791                            // list to be killed and restarted if needed for
18792                            // memory.
18793                            if (app.hasShownUi && app != mHomeProcess
18794                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18795                                adjType = "cch-bound-ui-services";
18796                            } else {
18797                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18798                                        |Context.BIND_IMPORTANT)) != 0) {
18799                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18800                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18801                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18802                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18803                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18804                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18805                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18806                                    adj = clientAdj;
18807                                } else {
18808                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18809                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18810                                    }
18811                                }
18812                                if (!client.cached) {
18813                                    app.cached = false;
18814                                }
18815                                adjType = "service";
18816                            }
18817                        }
18818                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18819                            // This will treat important bound services identically to
18820                            // the top app, which may behave differently than generic
18821                            // foreground work.
18822                            if (client.curSchedGroup > schedGroup) {
18823                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18824                                    schedGroup = client.curSchedGroup;
18825                                } else {
18826                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18827                                }
18828                            }
18829                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18830                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18831                                    // Special handling of clients who are in the top state.
18832                                    // We *may* want to consider this process to be in the
18833                                    // top state as well, but only if there is not another
18834                                    // reason for it to be running.  Being on the top is a
18835                                    // special state, meaning you are specifically running
18836                                    // for the current top app.  If the process is already
18837                                    // running in the background for some other reason, it
18838                                    // is more important to continue considering it to be
18839                                    // in the background state.
18840                                    mayBeTop = true;
18841                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18842                                } else {
18843                                    // Special handling for above-top states (persistent
18844                                    // processes).  These should not bring the current process
18845                                    // into the top state, since they are not on top.  Instead
18846                                    // give them the best state after that.
18847                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18848                                        clientProcState =
18849                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18850                                    } else if (mWakefulness
18851                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18852                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18853                                                    != 0) {
18854                                        clientProcState =
18855                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18856                                    } else {
18857                                        clientProcState =
18858                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18859                                    }
18860                                }
18861                            }
18862                        } else {
18863                            if (clientProcState <
18864                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18865                                clientProcState =
18866                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18867                            }
18868                        }
18869                        if (procState > clientProcState) {
18870                            procState = clientProcState;
18871                        }
18872                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18873                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18874                            app.pendingUiClean = true;
18875                        }
18876                        if (adjType != null) {
18877                            app.adjType = adjType;
18878                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18879                                    .REASON_SERVICE_IN_USE;
18880                            app.adjSource = cr.binding.client;
18881                            app.adjSourceProcState = clientProcState;
18882                            app.adjTarget = s.name;
18883                        }
18884                    }
18885                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18886                        app.treatLikeActivity = true;
18887                    }
18888                    final ActivityRecord a = cr.activity;
18889                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18890                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18891                            (a.visible || a.state == ActivityState.RESUMED ||
18892                             a.state == ActivityState.PAUSING)) {
18893                            adj = ProcessList.FOREGROUND_APP_ADJ;
18894                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18895                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18896                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18897                                } else {
18898                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18899                                }
18900                            }
18901                            app.cached = false;
18902                            app.adjType = "service";
18903                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18904                                    .REASON_SERVICE_IN_USE;
18905                            app.adjSource = a;
18906                            app.adjSourceProcState = procState;
18907                            app.adjTarget = s.name;
18908                        }
18909                    }
18910                }
18911            }
18912        }
18913
18914        for (int provi = app.pubProviders.size()-1;
18915                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18916                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18917                        || procState > ActivityManager.PROCESS_STATE_TOP);
18918                provi--) {
18919            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18920            for (int i = cpr.connections.size()-1;
18921                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18922                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18923                            || procState > ActivityManager.PROCESS_STATE_TOP);
18924                    i--) {
18925                ContentProviderConnection conn = cpr.connections.get(i);
18926                ProcessRecord client = conn.client;
18927                if (client == app) {
18928                    // Being our own client is not interesting.
18929                    continue;
18930                }
18931                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18932                int clientProcState = client.curProcState;
18933                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18934                    // If the other app is cached for any reason, for purposes here
18935                    // we are going to consider it empty.
18936                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18937                }
18938                if (adj > clientAdj) {
18939                    if (app.hasShownUi && app != mHomeProcess
18940                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18941                        app.adjType = "cch-ui-provider";
18942                    } else {
18943                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18944                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18945                        app.adjType = "provider";
18946                    }
18947                    app.cached &= client.cached;
18948                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18949                            .REASON_PROVIDER_IN_USE;
18950                    app.adjSource = client;
18951                    app.adjSourceProcState = clientProcState;
18952                    app.adjTarget = cpr.name;
18953                }
18954                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18955                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18956                        // Special handling of clients who are in the top state.
18957                        // We *may* want to consider this process to be in the
18958                        // top state as well, but only if there is not another
18959                        // reason for it to be running.  Being on the top is a
18960                        // special state, meaning you are specifically running
18961                        // for the current top app.  If the process is already
18962                        // running in the background for some other reason, it
18963                        // is more important to continue considering it to be
18964                        // in the background state.
18965                        mayBeTop = true;
18966                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18967                    } else {
18968                        // Special handling for above-top states (persistent
18969                        // processes).  These should not bring the current process
18970                        // into the top state, since they are not on top.  Instead
18971                        // give them the best state after that.
18972                        clientProcState =
18973                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18974                    }
18975                }
18976                if (procState > clientProcState) {
18977                    procState = clientProcState;
18978                }
18979                if (client.curSchedGroup > schedGroup) {
18980                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18981                }
18982            }
18983            // If the provider has external (non-framework) process
18984            // dependencies, ensure that its adjustment is at least
18985            // FOREGROUND_APP_ADJ.
18986            if (cpr.hasExternalProcessHandles()) {
18987                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18988                    adj = ProcessList.FOREGROUND_APP_ADJ;
18989                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18990                    app.cached = false;
18991                    app.adjType = "provider";
18992                    app.adjTarget = cpr.name;
18993                }
18994                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18995                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18996                }
18997            }
18998        }
18999
19000        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19001            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19002                adj = ProcessList.PREVIOUS_APP_ADJ;
19003                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19004                app.cached = false;
19005                app.adjType = "provider";
19006            }
19007            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19008                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19009            }
19010        }
19011
19012        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19013            // A client of one of our services or providers is in the top state.  We
19014            // *may* want to be in the top state, but not if we are already running in
19015            // the background for some other reason.  For the decision here, we are going
19016            // to pick out a few specific states that we want to remain in when a client
19017            // is top (states that tend to be longer-term) and otherwise allow it to go
19018            // to the top state.
19019            switch (procState) {
19020                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19021                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19022                case ActivityManager.PROCESS_STATE_SERVICE:
19023                    // These all are longer-term states, so pull them up to the top
19024                    // of the background states, but not all the way to the top state.
19025                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19026                    break;
19027                default:
19028                    // Otherwise, top is a better choice, so take it.
19029                    procState = ActivityManager.PROCESS_STATE_TOP;
19030                    break;
19031            }
19032        }
19033
19034        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19035            if (app.hasClientActivities) {
19036                // This is a cached process, but with client activities.  Mark it so.
19037                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19038                app.adjType = "cch-client-act";
19039            } else if (app.treatLikeActivity) {
19040                // This is a cached process, but somebody wants us to treat it like it has
19041                // an activity, okay!
19042                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19043                app.adjType = "cch-as-act";
19044            }
19045        }
19046
19047        if (adj == ProcessList.SERVICE_ADJ) {
19048            if (doingAll) {
19049                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19050                mNewNumServiceProcs++;
19051                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19052                if (!app.serviceb) {
19053                    // This service isn't far enough down on the LRU list to
19054                    // normally be a B service, but if we are low on RAM and it
19055                    // is large we want to force it down since we would prefer to
19056                    // keep launcher over it.
19057                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19058                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19059                        app.serviceHighRam = true;
19060                        app.serviceb = true;
19061                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19062                    } else {
19063                        mNewNumAServiceProcs++;
19064                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19065                    }
19066                } else {
19067                    app.serviceHighRam = false;
19068                }
19069            }
19070            if (app.serviceb) {
19071                adj = ProcessList.SERVICE_B_ADJ;
19072            }
19073        }
19074
19075        app.curRawAdj = adj;
19076
19077        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19078        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19079        if (adj > app.maxAdj) {
19080            adj = app.maxAdj;
19081            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19082                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19083            }
19084        }
19085
19086        // Do final modification to adj.  Everything we do between here and applying
19087        // the final setAdj must be done in this function, because we will also use
19088        // it when computing the final cached adj later.  Note that we don't need to
19089        // worry about this for max adj above, since max adj will always be used to
19090        // keep it out of the cached vaues.
19091        app.curAdj = app.modifyRawOomAdj(adj);
19092        app.curSchedGroup = schedGroup;
19093        app.curProcState = procState;
19094        app.foregroundActivities = foregroundActivities;
19095
19096        return app.curRawAdj;
19097    }
19098
19099    /**
19100     * Record new PSS sample for a process.
19101     */
19102    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19103            long now) {
19104        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19105                swapPss * 1024);
19106        proc.lastPssTime = now;
19107        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19108        if (DEBUG_PSS) Slog.d(TAG_PSS,
19109                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19110                + " state=" + ProcessList.makeProcStateString(procState));
19111        if (proc.initialIdlePss == 0) {
19112            proc.initialIdlePss = pss;
19113        }
19114        proc.lastPss = pss;
19115        proc.lastSwapPss = swapPss;
19116        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19117            proc.lastCachedPss = pss;
19118            proc.lastCachedSwapPss = swapPss;
19119        }
19120
19121        final SparseArray<Pair<Long, String>> watchUids
19122                = mMemWatchProcesses.getMap().get(proc.processName);
19123        Long check = null;
19124        if (watchUids != null) {
19125            Pair<Long, String> val = watchUids.get(proc.uid);
19126            if (val == null) {
19127                val = watchUids.get(0);
19128            }
19129            if (val != null) {
19130                check = val.first;
19131            }
19132        }
19133        if (check != null) {
19134            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19135                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19136                if (!isDebuggable) {
19137                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19138                        isDebuggable = true;
19139                    }
19140                }
19141                if (isDebuggable) {
19142                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19143                    final ProcessRecord myProc = proc;
19144                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19145                    mMemWatchDumpProcName = proc.processName;
19146                    mMemWatchDumpFile = heapdumpFile.toString();
19147                    mMemWatchDumpPid = proc.pid;
19148                    mMemWatchDumpUid = proc.uid;
19149                    BackgroundThread.getHandler().post(new Runnable() {
19150                        @Override
19151                        public void run() {
19152                            revokeUriPermission(ActivityThread.currentActivityThread()
19153                                            .getApplicationThread(),
19154                                    DumpHeapActivity.JAVA_URI,
19155                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19156                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19157                                    UserHandle.myUserId());
19158                            ParcelFileDescriptor fd = null;
19159                            try {
19160                                heapdumpFile.delete();
19161                                fd = ParcelFileDescriptor.open(heapdumpFile,
19162                                        ParcelFileDescriptor.MODE_CREATE |
19163                                                ParcelFileDescriptor.MODE_TRUNCATE |
19164                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19165                                                ParcelFileDescriptor.MODE_APPEND);
19166                                IApplicationThread thread = myProc.thread;
19167                                if (thread != null) {
19168                                    try {
19169                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19170                                                "Requesting dump heap from "
19171                                                + myProc + " to " + heapdumpFile);
19172                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19173                                    } catch (RemoteException e) {
19174                                    }
19175                                }
19176                            } catch (FileNotFoundException e) {
19177                                e.printStackTrace();
19178                            } finally {
19179                                if (fd != null) {
19180                                    try {
19181                                        fd.close();
19182                                    } catch (IOException e) {
19183                                    }
19184                                }
19185                            }
19186                        }
19187                    });
19188                } else {
19189                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19190                            + ", but debugging not enabled");
19191                }
19192            }
19193        }
19194    }
19195
19196    /**
19197     * Schedule PSS collection of a process.
19198     */
19199    void requestPssLocked(ProcessRecord proc, int procState) {
19200        if (mPendingPssProcesses.contains(proc)) {
19201            return;
19202        }
19203        if (mPendingPssProcesses.size() == 0) {
19204            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19205        }
19206        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19207        proc.pssProcState = procState;
19208        mPendingPssProcesses.add(proc);
19209    }
19210
19211    /**
19212     * Schedule PSS collection of all processes.
19213     */
19214    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19215        if (!always) {
19216            if (now < (mLastFullPssTime +
19217                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19218                return;
19219            }
19220        }
19221        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19222        mLastFullPssTime = now;
19223        mFullPssPending = true;
19224        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19225        mPendingPssProcesses.clear();
19226        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19227            ProcessRecord app = mLruProcesses.get(i);
19228            if (app.thread == null
19229                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19230                continue;
19231            }
19232            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19233                app.pssProcState = app.setProcState;
19234                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19235                        mTestPssMode, isSleeping(), now);
19236                mPendingPssProcesses.add(app);
19237            }
19238        }
19239        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19240    }
19241
19242    public void setTestPssMode(boolean enabled) {
19243        synchronized (this) {
19244            mTestPssMode = enabled;
19245            if (enabled) {
19246                // Whenever we enable the mode, we want to take a snapshot all of current
19247                // process mem use.
19248                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19249            }
19250        }
19251    }
19252
19253    /**
19254     * Ask a given process to GC right now.
19255     */
19256    final void performAppGcLocked(ProcessRecord app) {
19257        try {
19258            app.lastRequestedGc = SystemClock.uptimeMillis();
19259            if (app.thread != null) {
19260                if (app.reportLowMemory) {
19261                    app.reportLowMemory = false;
19262                    app.thread.scheduleLowMemory();
19263                } else {
19264                    app.thread.processInBackground();
19265                }
19266            }
19267        } catch (Exception e) {
19268            // whatever.
19269        }
19270    }
19271
19272    /**
19273     * Returns true if things are idle enough to perform GCs.
19274     */
19275    private final boolean canGcNowLocked() {
19276        boolean processingBroadcasts = false;
19277        for (BroadcastQueue q : mBroadcastQueues) {
19278            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19279                processingBroadcasts = true;
19280            }
19281        }
19282        return !processingBroadcasts
19283                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19284    }
19285
19286    /**
19287     * Perform GCs on all processes that are waiting for it, but only
19288     * if things are idle.
19289     */
19290    final void performAppGcsLocked() {
19291        final int N = mProcessesToGc.size();
19292        if (N <= 0) {
19293            return;
19294        }
19295        if (canGcNowLocked()) {
19296            while (mProcessesToGc.size() > 0) {
19297                ProcessRecord proc = mProcessesToGc.remove(0);
19298                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19299                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19300                            <= SystemClock.uptimeMillis()) {
19301                        // To avoid spamming the system, we will GC processes one
19302                        // at a time, waiting a few seconds between each.
19303                        performAppGcLocked(proc);
19304                        scheduleAppGcsLocked();
19305                        return;
19306                    } else {
19307                        // It hasn't been long enough since we last GCed this
19308                        // process...  put it in the list to wait for its time.
19309                        addProcessToGcListLocked(proc);
19310                        break;
19311                    }
19312                }
19313            }
19314
19315            scheduleAppGcsLocked();
19316        }
19317    }
19318
19319    /**
19320     * If all looks good, perform GCs on all processes waiting for them.
19321     */
19322    final void performAppGcsIfAppropriateLocked() {
19323        if (canGcNowLocked()) {
19324            performAppGcsLocked();
19325            return;
19326        }
19327        // Still not idle, wait some more.
19328        scheduleAppGcsLocked();
19329    }
19330
19331    /**
19332     * Schedule the execution of all pending app GCs.
19333     */
19334    final void scheduleAppGcsLocked() {
19335        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19336
19337        if (mProcessesToGc.size() > 0) {
19338            // Schedule a GC for the time to the next process.
19339            ProcessRecord proc = mProcessesToGc.get(0);
19340            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19341
19342            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19343            long now = SystemClock.uptimeMillis();
19344            if (when < (now+GC_TIMEOUT)) {
19345                when = now + GC_TIMEOUT;
19346            }
19347            mHandler.sendMessageAtTime(msg, when);
19348        }
19349    }
19350
19351    /**
19352     * Add a process to the array of processes waiting to be GCed.  Keeps the
19353     * list in sorted order by the last GC time.  The process can't already be
19354     * on the list.
19355     */
19356    final void addProcessToGcListLocked(ProcessRecord proc) {
19357        boolean added = false;
19358        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19359            if (mProcessesToGc.get(i).lastRequestedGc <
19360                    proc.lastRequestedGc) {
19361                added = true;
19362                mProcessesToGc.add(i+1, proc);
19363                break;
19364            }
19365        }
19366        if (!added) {
19367            mProcessesToGc.add(0, proc);
19368        }
19369    }
19370
19371    /**
19372     * Set up to ask a process to GC itself.  This will either do it
19373     * immediately, or put it on the list of processes to gc the next
19374     * time things are idle.
19375     */
19376    final void scheduleAppGcLocked(ProcessRecord app) {
19377        long now = SystemClock.uptimeMillis();
19378        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19379            return;
19380        }
19381        if (!mProcessesToGc.contains(app)) {
19382            addProcessToGcListLocked(app);
19383            scheduleAppGcsLocked();
19384        }
19385    }
19386
19387    final void checkExcessivePowerUsageLocked(boolean doKills) {
19388        updateCpuStatsNow();
19389
19390        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19391        boolean doWakeKills = doKills;
19392        boolean doCpuKills = doKills;
19393        if (mLastPowerCheckRealtime == 0) {
19394            doWakeKills = false;
19395        }
19396        if (mLastPowerCheckUptime == 0) {
19397            doCpuKills = false;
19398        }
19399        if (stats.isScreenOn()) {
19400            doWakeKills = false;
19401        }
19402        final long curRealtime = SystemClock.elapsedRealtime();
19403        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19404        final long curUptime = SystemClock.uptimeMillis();
19405        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19406        mLastPowerCheckRealtime = curRealtime;
19407        mLastPowerCheckUptime = curUptime;
19408        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19409            doWakeKills = false;
19410        }
19411        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19412            doCpuKills = false;
19413        }
19414        int i = mLruProcesses.size();
19415        while (i > 0) {
19416            i--;
19417            ProcessRecord app = mLruProcesses.get(i);
19418            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19419                long wtime;
19420                synchronized (stats) {
19421                    wtime = stats.getProcessWakeTime(app.info.uid,
19422                            app.pid, curRealtime);
19423                }
19424                long wtimeUsed = wtime - app.lastWakeTime;
19425                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19426                if (DEBUG_POWER) {
19427                    StringBuilder sb = new StringBuilder(128);
19428                    sb.append("Wake for ");
19429                    app.toShortString(sb);
19430                    sb.append(": over ");
19431                    TimeUtils.formatDuration(realtimeSince, sb);
19432                    sb.append(" used ");
19433                    TimeUtils.formatDuration(wtimeUsed, sb);
19434                    sb.append(" (");
19435                    sb.append((wtimeUsed*100)/realtimeSince);
19436                    sb.append("%)");
19437                    Slog.i(TAG_POWER, sb.toString());
19438                    sb.setLength(0);
19439                    sb.append("CPU for ");
19440                    app.toShortString(sb);
19441                    sb.append(": over ");
19442                    TimeUtils.formatDuration(uptimeSince, sb);
19443                    sb.append(" used ");
19444                    TimeUtils.formatDuration(cputimeUsed, sb);
19445                    sb.append(" (");
19446                    sb.append((cputimeUsed*100)/uptimeSince);
19447                    sb.append("%)");
19448                    Slog.i(TAG_POWER, sb.toString());
19449                }
19450                // If a process has held a wake lock for more
19451                // than 50% of the time during this period,
19452                // that sounds bad.  Kill!
19453                if (doWakeKills && realtimeSince > 0
19454                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19455                    synchronized (stats) {
19456                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19457                                realtimeSince, wtimeUsed);
19458                    }
19459                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19460                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19461                } else if (doCpuKills && uptimeSince > 0
19462                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19463                    synchronized (stats) {
19464                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19465                                uptimeSince, cputimeUsed);
19466                    }
19467                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19468                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19469                } else {
19470                    app.lastWakeTime = wtime;
19471                    app.lastCpuTime = app.curCpuTime;
19472                }
19473            }
19474        }
19475    }
19476
19477    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19478            long nowElapsed) {
19479        boolean success = true;
19480
19481        if (app.curRawAdj != app.setRawAdj) {
19482            app.setRawAdj = app.curRawAdj;
19483        }
19484
19485        int changes = 0;
19486
19487        if (app.curAdj != app.setAdj) {
19488            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19489            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19490                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19491                    + app.adjType);
19492            app.setAdj = app.curAdj;
19493        }
19494
19495        if (app.setSchedGroup != app.curSchedGroup) {
19496            app.setSchedGroup = app.curSchedGroup;
19497            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19498                    "Setting sched group of " + app.processName
19499                    + " to " + app.curSchedGroup);
19500            if (app.waitingToKill != null && app.curReceiver == null
19501                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19502                app.kill(app.waitingToKill, true);
19503                success = false;
19504            } else {
19505                int processGroup;
19506                switch (app.curSchedGroup) {
19507                    case ProcessList.SCHED_GROUP_BACKGROUND:
19508                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19509                        break;
19510                    case ProcessList.SCHED_GROUP_TOP_APP:
19511                        processGroup = Process.THREAD_GROUP_TOP_APP;
19512                        break;
19513                    default:
19514                        processGroup = Process.THREAD_GROUP_DEFAULT;
19515                        break;
19516                }
19517                if (true) {
19518                    long oldId = Binder.clearCallingIdentity();
19519                    try {
19520                        Process.setProcessGroup(app.pid, processGroup);
19521                    } catch (Exception e) {
19522                        Slog.w(TAG, "Failed setting process group of " + app.pid
19523                                + " to " + app.curSchedGroup);
19524                        e.printStackTrace();
19525                    } finally {
19526                        Binder.restoreCallingIdentity(oldId);
19527                    }
19528                } else {
19529                    if (app.thread != null) {
19530                        try {
19531                            app.thread.setSchedulingGroup(processGroup);
19532                        } catch (RemoteException e) {
19533                        }
19534                    }
19535                }
19536            }
19537        }
19538        if (app.repForegroundActivities != app.foregroundActivities) {
19539            app.repForegroundActivities = app.foregroundActivities;
19540            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19541        }
19542        if (app.repProcState != app.curProcState) {
19543            app.repProcState = app.curProcState;
19544            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19545            if (app.thread != null) {
19546                try {
19547                    if (false) {
19548                        //RuntimeException h = new RuntimeException("here");
19549                        Slog.i(TAG, "Sending new process state " + app.repProcState
19550                                + " to " + app /*, h*/);
19551                    }
19552                    app.thread.setProcessState(app.repProcState);
19553                } catch (RemoteException e) {
19554                }
19555            }
19556        }
19557        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19558                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19559            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19560                // Experimental code to more aggressively collect pss while
19561                // running test...  the problem is that this tends to collect
19562                // the data right when a process is transitioning between process
19563                // states, which well tend to give noisy data.
19564                long start = SystemClock.uptimeMillis();
19565                long pss = Debug.getPss(app.pid, mTmpLong, null);
19566                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19567                mPendingPssProcesses.remove(app);
19568                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19569                        + " to " + app.curProcState + ": "
19570                        + (SystemClock.uptimeMillis()-start) + "ms");
19571            }
19572            app.lastStateTime = now;
19573            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19574                    mTestPssMode, isSleeping(), now);
19575            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19576                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19577                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19578                    + (app.nextPssTime-now) + ": " + app);
19579        } else {
19580            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19581                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19582                    mTestPssMode)))) {
19583                requestPssLocked(app, app.setProcState);
19584                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19585                        mTestPssMode, isSleeping(), now);
19586            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19587                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19588        }
19589        if (app.setProcState != app.curProcState) {
19590            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19591                    "Proc state change of " + app.processName
19592                            + " to " + app.curProcState);
19593            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19594            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19595            if (setImportant && !curImportant) {
19596                // This app is no longer something we consider important enough to allow to
19597                // use arbitrary amounts of battery power.  Note
19598                // its current wake lock time to later know to kill it if
19599                // it is not behaving well.
19600                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19601                synchronized (stats) {
19602                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19603                            app.pid, nowElapsed);
19604                }
19605                app.lastCpuTime = app.curCpuTime;
19606
19607            }
19608            // Inform UsageStats of important process state change
19609            // Must be called before updating setProcState
19610            maybeUpdateUsageStatsLocked(app, nowElapsed);
19611
19612            app.setProcState = app.curProcState;
19613            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19614                app.notCachedSinceIdle = false;
19615            }
19616            if (!doingAll) {
19617                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19618            } else {
19619                app.procStateChanged = true;
19620            }
19621        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19622                > USAGE_STATS_INTERACTION_INTERVAL) {
19623            // For apps that sit around for a long time in the interactive state, we need
19624            // to report this at least once a day so they don't go idle.
19625            maybeUpdateUsageStatsLocked(app, nowElapsed);
19626        }
19627
19628        if (changes != 0) {
19629            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19630                    "Changes in " + app + ": " + changes);
19631            int i = mPendingProcessChanges.size()-1;
19632            ProcessChangeItem item = null;
19633            while (i >= 0) {
19634                item = mPendingProcessChanges.get(i);
19635                if (item.pid == app.pid) {
19636                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19637                            "Re-using existing item: " + item);
19638                    break;
19639                }
19640                i--;
19641            }
19642            if (i < 0) {
19643                // No existing item in pending changes; need a new one.
19644                final int NA = mAvailProcessChanges.size();
19645                if (NA > 0) {
19646                    item = mAvailProcessChanges.remove(NA-1);
19647                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19648                            "Retrieving available item: " + item);
19649                } else {
19650                    item = new ProcessChangeItem();
19651                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19652                            "Allocating new item: " + item);
19653                }
19654                item.changes = 0;
19655                item.pid = app.pid;
19656                item.uid = app.info.uid;
19657                if (mPendingProcessChanges.size() == 0) {
19658                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19659                            "*** Enqueueing dispatch processes changed!");
19660                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19661                }
19662                mPendingProcessChanges.add(item);
19663            }
19664            item.changes |= changes;
19665            item.processState = app.repProcState;
19666            item.foregroundActivities = app.repForegroundActivities;
19667            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19668                    "Item " + Integer.toHexString(System.identityHashCode(item))
19669                    + " " + app.toShortString() + ": changes=" + item.changes
19670                    + " procState=" + item.processState
19671                    + " foreground=" + item.foregroundActivities
19672                    + " type=" + app.adjType + " source=" + app.adjSource
19673                    + " target=" + app.adjTarget);
19674        }
19675
19676        return success;
19677    }
19678
19679    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19680        final UidRecord.ChangeItem pendingChange;
19681        if (uidRec == null || uidRec.pendingChange == null) {
19682            if (mPendingUidChanges.size() == 0) {
19683                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19684                        "*** Enqueueing dispatch uid changed!");
19685                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19686            }
19687            final int NA = mAvailUidChanges.size();
19688            if (NA > 0) {
19689                pendingChange = mAvailUidChanges.remove(NA-1);
19690                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19691                        "Retrieving available item: " + pendingChange);
19692            } else {
19693                pendingChange = new UidRecord.ChangeItem();
19694                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19695                        "Allocating new item: " + pendingChange);
19696            }
19697            if (uidRec != null) {
19698                uidRec.pendingChange = pendingChange;
19699                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19700                    // If this uid is going away, and we haven't yet reported it is gone,
19701                    // then do so now.
19702                    change = UidRecord.CHANGE_GONE_IDLE;
19703                }
19704            } else if (uid < 0) {
19705                throw new IllegalArgumentException("No UidRecord or uid");
19706            }
19707            pendingChange.uidRecord = uidRec;
19708            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19709            mPendingUidChanges.add(pendingChange);
19710        } else {
19711            pendingChange = uidRec.pendingChange;
19712            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19713                change = UidRecord.CHANGE_GONE_IDLE;
19714            }
19715        }
19716        pendingChange.change = change;
19717        pendingChange.processState = uidRec != null
19718                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19719    }
19720
19721    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19722            String authority) {
19723        if (app == null) return;
19724        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19725            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19726            if (userState == null) return;
19727            final long now = SystemClock.elapsedRealtime();
19728            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19729            if (lastReported == null || lastReported < now - 60 * 1000L) {
19730                mUsageStatsService.reportContentProviderUsage(
19731                        authority, providerPkgName, app.userId);
19732                userState.mProviderLastReportedFg.put(authority, now);
19733            }
19734        }
19735    }
19736
19737    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19738        if (DEBUG_USAGE_STATS) {
19739            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19740                    + "] state changes: old = " + app.setProcState + ", new = "
19741                    + app.curProcState);
19742        }
19743        if (mUsageStatsService == null) {
19744            return;
19745        }
19746        boolean isInteraction;
19747        // To avoid some abuse patterns, we are going to be careful about what we consider
19748        // to be an app interaction.  Being the top activity doesn't count while the display
19749        // is sleeping, nor do short foreground services.
19750        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19751            isInteraction = true;
19752            app.fgInteractionTime = 0;
19753        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19754            if (app.fgInteractionTime == 0) {
19755                app.fgInteractionTime = nowElapsed;
19756                isInteraction = false;
19757            } else {
19758                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19759            }
19760        } else {
19761            isInteraction = app.curProcState
19762                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19763            app.fgInteractionTime = 0;
19764        }
19765        if (isInteraction && (!app.reportedInteraction
19766                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19767            app.interactionEventTime = nowElapsed;
19768            String[] packages = app.getPackageList();
19769            if (packages != null) {
19770                for (int i = 0; i < packages.length; i++) {
19771                    mUsageStatsService.reportEvent(packages[i], app.userId,
19772                            UsageEvents.Event.SYSTEM_INTERACTION);
19773                }
19774            }
19775        }
19776        app.reportedInteraction = isInteraction;
19777        if (!isInteraction) {
19778            app.interactionEventTime = 0;
19779        }
19780    }
19781
19782    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19783        if (proc.thread != null) {
19784            if (proc.baseProcessTracker != null) {
19785                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19786            }
19787        }
19788    }
19789
19790    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19791            ProcessRecord TOP_APP, boolean doingAll, long now) {
19792        if (app.thread == null) {
19793            return false;
19794        }
19795
19796        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19797
19798        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19799    }
19800
19801    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19802            boolean oomAdj) {
19803        if (isForeground != proc.foregroundServices) {
19804            proc.foregroundServices = isForeground;
19805            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19806                    proc.info.uid);
19807            if (isForeground) {
19808                if (curProcs == null) {
19809                    curProcs = new ArrayList<ProcessRecord>();
19810                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19811                }
19812                if (!curProcs.contains(proc)) {
19813                    curProcs.add(proc);
19814                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19815                            proc.info.packageName, proc.info.uid);
19816                }
19817            } else {
19818                if (curProcs != null) {
19819                    if (curProcs.remove(proc)) {
19820                        mBatteryStatsService.noteEvent(
19821                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19822                                proc.info.packageName, proc.info.uid);
19823                        if (curProcs.size() <= 0) {
19824                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19825                        }
19826                    }
19827                }
19828            }
19829            if (oomAdj) {
19830                updateOomAdjLocked();
19831            }
19832        }
19833    }
19834
19835    private final ActivityRecord resumedAppLocked() {
19836        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19837        String pkg;
19838        int uid;
19839        if (act != null) {
19840            pkg = act.packageName;
19841            uid = act.info.applicationInfo.uid;
19842        } else {
19843            pkg = null;
19844            uid = -1;
19845        }
19846        // Has the UID or resumed package name changed?
19847        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19848                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19849            if (mCurResumedPackage != null) {
19850                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19851                        mCurResumedPackage, mCurResumedUid);
19852            }
19853            mCurResumedPackage = pkg;
19854            mCurResumedUid = uid;
19855            if (mCurResumedPackage != null) {
19856                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19857                        mCurResumedPackage, mCurResumedUid);
19858            }
19859        }
19860        return act;
19861    }
19862
19863    final boolean updateOomAdjLocked(ProcessRecord app) {
19864        final ActivityRecord TOP_ACT = resumedAppLocked();
19865        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19866        final boolean wasCached = app.cached;
19867
19868        mAdjSeq++;
19869
19870        // This is the desired cached adjusment we want to tell it to use.
19871        // If our app is currently cached, we know it, and that is it.  Otherwise,
19872        // we don't know it yet, and it needs to now be cached we will then
19873        // need to do a complete oom adj.
19874        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19875                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19876        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19877                SystemClock.uptimeMillis());
19878        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19879            // Changed to/from cached state, so apps after it in the LRU
19880            // list may also be changed.
19881            updateOomAdjLocked();
19882        }
19883        return success;
19884    }
19885
19886    final void updateOomAdjLocked() {
19887        final ActivityRecord TOP_ACT = resumedAppLocked();
19888        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19889        final long now = SystemClock.uptimeMillis();
19890        final long nowElapsed = SystemClock.elapsedRealtime();
19891        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19892        final int N = mLruProcesses.size();
19893
19894        if (false) {
19895            RuntimeException e = new RuntimeException();
19896            e.fillInStackTrace();
19897            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19898        }
19899
19900        // Reset state in all uid records.
19901        for (int i=mActiveUids.size()-1; i>=0; i--) {
19902            final UidRecord uidRec = mActiveUids.valueAt(i);
19903            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19904                    "Starting update of " + uidRec);
19905            uidRec.reset();
19906        }
19907
19908        mStackSupervisor.rankTaskLayersIfNeeded();
19909
19910        mAdjSeq++;
19911        mNewNumServiceProcs = 0;
19912        mNewNumAServiceProcs = 0;
19913
19914        final int emptyProcessLimit;
19915        final int cachedProcessLimit;
19916        if (mProcessLimit <= 0) {
19917            emptyProcessLimit = cachedProcessLimit = 0;
19918        } else if (mProcessLimit == 1) {
19919            emptyProcessLimit = 1;
19920            cachedProcessLimit = 0;
19921        } else {
19922            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19923            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19924        }
19925
19926        // Let's determine how many processes we have running vs.
19927        // how many slots we have for background processes; we may want
19928        // to put multiple processes in a slot of there are enough of
19929        // them.
19930        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19931                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19932        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19933        if (numEmptyProcs > cachedProcessLimit) {
19934            // If there are more empty processes than our limit on cached
19935            // processes, then use the cached process limit for the factor.
19936            // This ensures that the really old empty processes get pushed
19937            // down to the bottom, so if we are running low on memory we will
19938            // have a better chance at keeping around more cached processes
19939            // instead of a gazillion empty processes.
19940            numEmptyProcs = cachedProcessLimit;
19941        }
19942        int emptyFactor = numEmptyProcs/numSlots;
19943        if (emptyFactor < 1) emptyFactor = 1;
19944        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19945        if (cachedFactor < 1) cachedFactor = 1;
19946        int stepCached = 0;
19947        int stepEmpty = 0;
19948        int numCached = 0;
19949        int numEmpty = 0;
19950        int numTrimming = 0;
19951
19952        mNumNonCachedProcs = 0;
19953        mNumCachedHiddenProcs = 0;
19954
19955        // First update the OOM adjustment for each of the
19956        // application processes based on their current state.
19957        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19958        int nextCachedAdj = curCachedAdj+1;
19959        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19960        int nextEmptyAdj = curEmptyAdj+2;
19961        for (int i=N-1; i>=0; i--) {
19962            ProcessRecord app = mLruProcesses.get(i);
19963            if (!app.killedByAm && app.thread != null) {
19964                app.procStateChanged = false;
19965                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19966
19967                // If we haven't yet assigned the final cached adj
19968                // to the process, do that now.
19969                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19970                    switch (app.curProcState) {
19971                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19972                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19973                            // This process is a cached process holding activities...
19974                            // assign it the next cached value for that type, and then
19975                            // step that cached level.
19976                            app.curRawAdj = curCachedAdj;
19977                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19978                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19979                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19980                                    + ")");
19981                            if (curCachedAdj != nextCachedAdj) {
19982                                stepCached++;
19983                                if (stepCached >= cachedFactor) {
19984                                    stepCached = 0;
19985                                    curCachedAdj = nextCachedAdj;
19986                                    nextCachedAdj += 2;
19987                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19988                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19989                                    }
19990                                }
19991                            }
19992                            break;
19993                        default:
19994                            // For everything else, assign next empty cached process
19995                            // level and bump that up.  Note that this means that
19996                            // long-running services that have dropped down to the
19997                            // cached level will be treated as empty (since their process
19998                            // state is still as a service), which is what we want.
19999                            app.curRawAdj = curEmptyAdj;
20000                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20001                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20002                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20003                                    + ")");
20004                            if (curEmptyAdj != nextEmptyAdj) {
20005                                stepEmpty++;
20006                                if (stepEmpty >= emptyFactor) {
20007                                    stepEmpty = 0;
20008                                    curEmptyAdj = nextEmptyAdj;
20009                                    nextEmptyAdj += 2;
20010                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20011                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20012                                    }
20013                                }
20014                            }
20015                            break;
20016                    }
20017                }
20018
20019                applyOomAdjLocked(app, true, now, nowElapsed);
20020
20021                // Count the number of process types.
20022                switch (app.curProcState) {
20023                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20024                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20025                        mNumCachedHiddenProcs++;
20026                        numCached++;
20027                        if (numCached > cachedProcessLimit) {
20028                            app.kill("cached #" + numCached, true);
20029                        }
20030                        break;
20031                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20032                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20033                                && app.lastActivityTime < oldTime) {
20034                            app.kill("empty for "
20035                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20036                                    / 1000) + "s", true);
20037                        } else {
20038                            numEmpty++;
20039                            if (numEmpty > emptyProcessLimit) {
20040                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20041                            }
20042                        }
20043                        break;
20044                    default:
20045                        mNumNonCachedProcs++;
20046                        break;
20047                }
20048
20049                if (app.isolated && app.services.size() <= 0) {
20050                    // If this is an isolated process, and there are no
20051                    // services running in it, then the process is no longer
20052                    // needed.  We agressively kill these because we can by
20053                    // definition not re-use the same process again, and it is
20054                    // good to avoid having whatever code was running in them
20055                    // left sitting around after no longer needed.
20056                    app.kill("isolated not needed", true);
20057                } else {
20058                    // Keeping this process, update its uid.
20059                    final UidRecord uidRec = app.uidRecord;
20060                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20061                        uidRec.curProcState = app.curProcState;
20062                    }
20063                }
20064
20065                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20066                        && !app.killedByAm) {
20067                    numTrimming++;
20068                }
20069            }
20070        }
20071
20072        mNumServiceProcs = mNewNumServiceProcs;
20073
20074        // Now determine the memory trimming level of background processes.
20075        // Unfortunately we need to start at the back of the list to do this
20076        // properly.  We only do this if the number of background apps we
20077        // are managing to keep around is less than half the maximum we desire;
20078        // if we are keeping a good number around, we'll let them use whatever
20079        // memory they want.
20080        final int numCachedAndEmpty = numCached + numEmpty;
20081        int memFactor;
20082        if (numCached <= ProcessList.TRIM_CACHED_APPS
20083                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20084            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20085                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20086            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20087                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20088            } else {
20089                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20090            }
20091        } else {
20092            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20093        }
20094        // We always allow the memory level to go up (better).  We only allow it to go
20095        // down if we are in a state where that is allowed, *and* the total number of processes
20096        // has gone down since last time.
20097        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20098                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20099                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20100        if (memFactor > mLastMemoryLevel) {
20101            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20102                memFactor = mLastMemoryLevel;
20103                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20104            }
20105        }
20106        mLastMemoryLevel = memFactor;
20107        mLastNumProcesses = mLruProcesses.size();
20108        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20109        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20110        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20111            if (mLowRamStartTime == 0) {
20112                mLowRamStartTime = now;
20113            }
20114            int step = 0;
20115            int fgTrimLevel;
20116            switch (memFactor) {
20117                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20118                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20119                    break;
20120                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20121                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20122                    break;
20123                default:
20124                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20125                    break;
20126            }
20127            int factor = numTrimming/3;
20128            int minFactor = 2;
20129            if (mHomeProcess != null) minFactor++;
20130            if (mPreviousProcess != null) minFactor++;
20131            if (factor < minFactor) factor = minFactor;
20132            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20133            for (int i=N-1; i>=0; i--) {
20134                ProcessRecord app = mLruProcesses.get(i);
20135                if (allChanged || app.procStateChanged) {
20136                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20137                    app.procStateChanged = false;
20138                }
20139                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20140                        && !app.killedByAm) {
20141                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20142                        try {
20143                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20144                                    "Trimming memory of " + app.processName + " to " + curLevel);
20145                            app.thread.scheduleTrimMemory(curLevel);
20146                        } catch (RemoteException e) {
20147                        }
20148                        if (false) {
20149                            // For now we won't do this; our memory trimming seems
20150                            // to be good enough at this point that destroying
20151                            // activities causes more harm than good.
20152                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20153                                    && app != mHomeProcess && app != mPreviousProcess) {
20154                                // Need to do this on its own message because the stack may not
20155                                // be in a consistent state at this point.
20156                                // For these apps we will also finish their activities
20157                                // to help them free memory.
20158                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20159                            }
20160                        }
20161                    }
20162                    app.trimMemoryLevel = curLevel;
20163                    step++;
20164                    if (step >= factor) {
20165                        step = 0;
20166                        switch (curLevel) {
20167                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20168                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20169                                break;
20170                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20171                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20172                                break;
20173                        }
20174                    }
20175                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20176                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20177                            && app.thread != null) {
20178                        try {
20179                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20180                                    "Trimming memory of heavy-weight " + app.processName
20181                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20182                            app.thread.scheduleTrimMemory(
20183                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20184                        } catch (RemoteException e) {
20185                        }
20186                    }
20187                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20188                } else {
20189                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20190                            || app.systemNoUi) && app.pendingUiClean) {
20191                        // If this application is now in the background and it
20192                        // had done UI, then give it the special trim level to
20193                        // have it free UI resources.
20194                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20195                        if (app.trimMemoryLevel < level && app.thread != null) {
20196                            try {
20197                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20198                                        "Trimming memory of bg-ui " + app.processName
20199                                        + " to " + level);
20200                                app.thread.scheduleTrimMemory(level);
20201                            } catch (RemoteException e) {
20202                            }
20203                        }
20204                        app.pendingUiClean = false;
20205                    }
20206                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20207                        try {
20208                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20209                                    "Trimming memory of fg " + app.processName
20210                                    + " to " + fgTrimLevel);
20211                            app.thread.scheduleTrimMemory(fgTrimLevel);
20212                        } catch (RemoteException e) {
20213                        }
20214                    }
20215                    app.trimMemoryLevel = fgTrimLevel;
20216                }
20217            }
20218        } else {
20219            if (mLowRamStartTime != 0) {
20220                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20221                mLowRamStartTime = 0;
20222            }
20223            for (int i=N-1; i>=0; i--) {
20224                ProcessRecord app = mLruProcesses.get(i);
20225                if (allChanged || app.procStateChanged) {
20226                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20227                    app.procStateChanged = false;
20228                }
20229                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20230                        || app.systemNoUi) && app.pendingUiClean) {
20231                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20232                            && app.thread != null) {
20233                        try {
20234                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20235                                    "Trimming memory of ui hidden " + app.processName
20236                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20237                            app.thread.scheduleTrimMemory(
20238                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20239                        } catch (RemoteException e) {
20240                        }
20241                    }
20242                    app.pendingUiClean = false;
20243                }
20244                app.trimMemoryLevel = 0;
20245            }
20246        }
20247
20248        if (mAlwaysFinishActivities) {
20249            // Need to do this on its own message because the stack may not
20250            // be in a consistent state at this point.
20251            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20252        }
20253
20254        if (allChanged) {
20255            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20256        }
20257
20258        // Update from any uid changes.
20259        for (int i=mActiveUids.size()-1; i>=0; i--) {
20260            final UidRecord uidRec = mActiveUids.valueAt(i);
20261            int uidChange = UidRecord.CHANGE_PROCSTATE;
20262            if (uidRec.setProcState != uidRec.curProcState) {
20263                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20264                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20265                        + " to " + uidRec.curProcState);
20266                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20267                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20268                        uidRec.lastBackgroundTime = nowElapsed;
20269                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20270                            // Note: the background settle time is in elapsed realtime, while
20271                            // the handler time base is uptime.  All this means is that we may
20272                            // stop background uids later than we had intended, but that only
20273                            // happens because the device was sleeping so we are okay anyway.
20274                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20275                        }
20276                    }
20277                } else {
20278                    if (uidRec.idle) {
20279                        uidChange = UidRecord.CHANGE_ACTIVE;
20280                        uidRec.idle = false;
20281                    }
20282                    uidRec.lastBackgroundTime = 0;
20283                }
20284                uidRec.setProcState = uidRec.curProcState;
20285                enqueueUidChangeLocked(uidRec, -1, uidChange);
20286                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20287            }
20288        }
20289
20290        if (mProcessStats.shouldWriteNowLocked(now)) {
20291            mHandler.post(new Runnable() {
20292                @Override public void run() {
20293                    synchronized (ActivityManagerService.this) {
20294                        mProcessStats.writeStateAsyncLocked();
20295                    }
20296                }
20297            });
20298        }
20299
20300        if (DEBUG_OOM_ADJ) {
20301            final long duration = SystemClock.uptimeMillis() - now;
20302            if (false) {
20303                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20304                        new RuntimeException("here").fillInStackTrace());
20305            } else {
20306                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20307            }
20308        }
20309    }
20310
20311    final void idleUids() {
20312        synchronized (this) {
20313            final long nowElapsed = SystemClock.elapsedRealtime();
20314            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20315            long nextTime = 0;
20316            for (int i=mActiveUids.size()-1; i>=0; i--) {
20317                final UidRecord uidRec = mActiveUids.valueAt(i);
20318                final long bgTime = uidRec.lastBackgroundTime;
20319                if (bgTime > 0 && !uidRec.idle) {
20320                    if (bgTime <= maxBgTime) {
20321                        uidRec.idle = true;
20322                        doStopUidLocked(uidRec.uid, uidRec);
20323                    } else {
20324                        if (nextTime == 0 || nextTime > bgTime) {
20325                            nextTime = bgTime;
20326                        }
20327                    }
20328                }
20329            }
20330            if (nextTime > 0) {
20331                mHandler.removeMessages(IDLE_UIDS_MSG);
20332                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20333                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20334            }
20335        }
20336    }
20337
20338    final void runInBackgroundDisabled(int uid) {
20339        synchronized (this) {
20340            UidRecord uidRec = mActiveUids.get(uid);
20341            if (uidRec != null) {
20342                // This uid is actually running...  should it be considered background now?
20343                if (uidRec.idle) {
20344                    doStopUidLocked(uidRec.uid, uidRec);
20345                }
20346            } else {
20347                // This uid isn't actually running...  still send a report about it being "stopped".
20348                doStopUidLocked(uid, null);
20349            }
20350        }
20351    }
20352
20353    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20354        mServices.stopInBackgroundLocked(uid);
20355        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20356    }
20357
20358    final void trimApplications() {
20359        synchronized (this) {
20360            int i;
20361
20362            // First remove any unused application processes whose package
20363            // has been removed.
20364            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20365                final ProcessRecord app = mRemovedProcesses.get(i);
20366                if (app.activities.size() == 0
20367                        && app.curReceiver == null && app.services.size() == 0) {
20368                    Slog.i(
20369                        TAG, "Exiting empty application process "
20370                        + app.processName + " ("
20371                        + (app.thread != null ? app.thread.asBinder() : null)
20372                        + ")\n");
20373                    if (app.pid > 0 && app.pid != MY_PID) {
20374                        app.kill("empty", false);
20375                    } else {
20376                        try {
20377                            app.thread.scheduleExit();
20378                        } catch (Exception e) {
20379                            // Ignore exceptions.
20380                        }
20381                    }
20382                    cleanUpApplicationRecordLocked(app, false, true, -1);
20383                    mRemovedProcesses.remove(i);
20384
20385                    if (app.persistent) {
20386                        addAppLocked(app.info, false, null /* ABI override */);
20387                    }
20388                }
20389            }
20390
20391            // Now update the oom adj for all processes.
20392            updateOomAdjLocked();
20393        }
20394    }
20395
20396    /** This method sends the specified signal to each of the persistent apps */
20397    public void signalPersistentProcesses(int sig) throws RemoteException {
20398        if (sig != Process.SIGNAL_USR1) {
20399            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20400        }
20401
20402        synchronized (this) {
20403            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20404                    != PackageManager.PERMISSION_GRANTED) {
20405                throw new SecurityException("Requires permission "
20406                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20407            }
20408
20409            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20410                ProcessRecord r = mLruProcesses.get(i);
20411                if (r.thread != null && r.persistent) {
20412                    Process.sendSignal(r.pid, sig);
20413                }
20414            }
20415        }
20416    }
20417
20418    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20419        if (proc == null || proc == mProfileProc) {
20420            proc = mProfileProc;
20421            profileType = mProfileType;
20422            clearProfilerLocked();
20423        }
20424        if (proc == null) {
20425            return;
20426        }
20427        try {
20428            proc.thread.profilerControl(false, null, profileType);
20429        } catch (RemoteException e) {
20430            throw new IllegalStateException("Process disappeared");
20431        }
20432    }
20433
20434    private void clearProfilerLocked() {
20435        if (mProfileFd != null) {
20436            try {
20437                mProfileFd.close();
20438            } catch (IOException e) {
20439            }
20440        }
20441        mProfileApp = null;
20442        mProfileProc = null;
20443        mProfileFile = null;
20444        mProfileType = 0;
20445        mAutoStopProfiler = false;
20446        mSamplingInterval = 0;
20447    }
20448
20449    public boolean profileControl(String process, int userId, boolean start,
20450            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20451
20452        try {
20453            synchronized (this) {
20454                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20455                // its own permission.
20456                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20457                        != PackageManager.PERMISSION_GRANTED) {
20458                    throw new SecurityException("Requires permission "
20459                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20460                }
20461
20462                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20463                    throw new IllegalArgumentException("null profile info or fd");
20464                }
20465
20466                ProcessRecord proc = null;
20467                if (process != null) {
20468                    proc = findProcessLocked(process, userId, "profileControl");
20469                }
20470
20471                if (start && (proc == null || proc.thread == null)) {
20472                    throw new IllegalArgumentException("Unknown process: " + process);
20473                }
20474
20475                if (start) {
20476                    stopProfilerLocked(null, 0);
20477                    setProfileApp(proc.info, proc.processName, profilerInfo);
20478                    mProfileProc = proc;
20479                    mProfileType = profileType;
20480                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20481                    try {
20482                        fd = fd.dup();
20483                    } catch (IOException e) {
20484                        fd = null;
20485                    }
20486                    profilerInfo.profileFd = fd;
20487                    proc.thread.profilerControl(start, profilerInfo, profileType);
20488                    fd = null;
20489                    mProfileFd = null;
20490                } else {
20491                    stopProfilerLocked(proc, profileType);
20492                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20493                        try {
20494                            profilerInfo.profileFd.close();
20495                        } catch (IOException e) {
20496                        }
20497                    }
20498                }
20499
20500                return true;
20501            }
20502        } catch (RemoteException e) {
20503            throw new IllegalStateException("Process disappeared");
20504        } finally {
20505            if (profilerInfo != null && profilerInfo.profileFd != null) {
20506                try {
20507                    profilerInfo.profileFd.close();
20508                } catch (IOException e) {
20509                }
20510            }
20511        }
20512    }
20513
20514    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20515        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20516                userId, true, ALLOW_FULL_ONLY, callName, null);
20517        ProcessRecord proc = null;
20518        try {
20519            int pid = Integer.parseInt(process);
20520            synchronized (mPidsSelfLocked) {
20521                proc = mPidsSelfLocked.get(pid);
20522            }
20523        } catch (NumberFormatException e) {
20524        }
20525
20526        if (proc == null) {
20527            ArrayMap<String, SparseArray<ProcessRecord>> all
20528                    = mProcessNames.getMap();
20529            SparseArray<ProcessRecord> procs = all.get(process);
20530            if (procs != null && procs.size() > 0) {
20531                proc = procs.valueAt(0);
20532                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20533                    for (int i=1; i<procs.size(); i++) {
20534                        ProcessRecord thisProc = procs.valueAt(i);
20535                        if (thisProc.userId == userId) {
20536                            proc = thisProc;
20537                            break;
20538                        }
20539                    }
20540                }
20541            }
20542        }
20543
20544        return proc;
20545    }
20546
20547    public boolean dumpHeap(String process, int userId, boolean managed,
20548            String path, ParcelFileDescriptor fd) throws RemoteException {
20549
20550        try {
20551            synchronized (this) {
20552                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20553                // its own permission (same as profileControl).
20554                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20555                        != PackageManager.PERMISSION_GRANTED) {
20556                    throw new SecurityException("Requires permission "
20557                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20558                }
20559
20560                if (fd == null) {
20561                    throw new IllegalArgumentException("null fd");
20562                }
20563
20564                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20565                if (proc == null || proc.thread == null) {
20566                    throw new IllegalArgumentException("Unknown process: " + process);
20567                }
20568
20569                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20570                if (!isDebuggable) {
20571                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20572                        throw new SecurityException("Process not debuggable: " + proc);
20573                    }
20574                }
20575
20576                proc.thread.dumpHeap(managed, path, fd);
20577                fd = null;
20578                return true;
20579            }
20580        } catch (RemoteException e) {
20581            throw new IllegalStateException("Process disappeared");
20582        } finally {
20583            if (fd != null) {
20584                try {
20585                    fd.close();
20586                } catch (IOException e) {
20587                }
20588            }
20589        }
20590    }
20591
20592    @Override
20593    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20594            String reportPackage) {
20595        if (processName != null) {
20596            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20597                    "setDumpHeapDebugLimit()");
20598        } else {
20599            synchronized (mPidsSelfLocked) {
20600                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20601                if (proc == null) {
20602                    throw new SecurityException("No process found for calling pid "
20603                            + Binder.getCallingPid());
20604                }
20605                if (!Build.IS_DEBUGGABLE
20606                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20607                    throw new SecurityException("Not running a debuggable build");
20608                }
20609                processName = proc.processName;
20610                uid = proc.uid;
20611                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20612                    throw new SecurityException("Package " + reportPackage + " is not running in "
20613                            + proc);
20614                }
20615            }
20616        }
20617        synchronized (this) {
20618            if (maxMemSize > 0) {
20619                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20620            } else {
20621                if (uid != 0) {
20622                    mMemWatchProcesses.remove(processName, uid);
20623                } else {
20624                    mMemWatchProcesses.getMap().remove(processName);
20625                }
20626            }
20627        }
20628    }
20629
20630    @Override
20631    public void dumpHeapFinished(String path) {
20632        synchronized (this) {
20633            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20634                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20635                        + " does not match last pid " + mMemWatchDumpPid);
20636                return;
20637            }
20638            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20639                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20640                        + " does not match last path " + mMemWatchDumpFile);
20641                return;
20642            }
20643            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20644            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20645        }
20646    }
20647
20648    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20649    public void monitor() {
20650        synchronized (this) { }
20651    }
20652
20653    void onCoreSettingsChange(Bundle settings) {
20654        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20655            ProcessRecord processRecord = mLruProcesses.get(i);
20656            try {
20657                if (processRecord.thread != null) {
20658                    processRecord.thread.setCoreSettings(settings);
20659                }
20660            } catch (RemoteException re) {
20661                /* ignore */
20662            }
20663        }
20664    }
20665
20666    // Multi-user methods
20667
20668    /**
20669     * Start user, if its not already running, but don't bring it to foreground.
20670     */
20671    @Override
20672    public boolean startUserInBackground(final int userId) {
20673        return mUserController.startUser(userId, /* foreground */ false);
20674    }
20675
20676    @Override
20677    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20678        return mUserController.unlockUser(userId, token, secret, listener);
20679    }
20680
20681    @Override
20682    public boolean switchUser(final int targetUserId) {
20683        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20684        UserInfo currentUserInfo;
20685        UserInfo targetUserInfo;
20686        synchronized (this) {
20687            int currentUserId = mUserController.getCurrentUserIdLocked();
20688            currentUserInfo = mUserController.getUserInfo(currentUserId);
20689            targetUserInfo = mUserController.getUserInfo(targetUserId);
20690            if (targetUserInfo == null) {
20691                Slog.w(TAG, "No user info for user #" + targetUserId);
20692                return false;
20693            }
20694            if (!targetUserInfo.supportsSwitchTo()) {
20695                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20696                return false;
20697            }
20698            if (targetUserInfo.isManagedProfile()) {
20699                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20700                return false;
20701            }
20702            mUserController.setTargetUserIdLocked(targetUserId);
20703        }
20704        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20705        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20706        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20707        return true;
20708    }
20709
20710    void scheduleStartProfilesLocked() {
20711        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20712            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20713                    DateUtils.SECOND_IN_MILLIS);
20714        }
20715    }
20716
20717    @Override
20718    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20719        return mUserController.stopUser(userId, force, callback);
20720    }
20721
20722    @Override
20723    public UserInfo getCurrentUser() {
20724        return mUserController.getCurrentUser();
20725    }
20726
20727    @Override
20728    public boolean isUserRunning(int userId, int flags) {
20729        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20730                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20731            String msg = "Permission Denial: isUserRunning() from pid="
20732                    + Binder.getCallingPid()
20733                    + ", uid=" + Binder.getCallingUid()
20734                    + " requires " + INTERACT_ACROSS_USERS;
20735            Slog.w(TAG, msg);
20736            throw new SecurityException(msg);
20737        }
20738        synchronized (this) {
20739            return mUserController.isUserRunningLocked(userId, flags);
20740        }
20741    }
20742
20743    @Override
20744    public int[] getRunningUserIds() {
20745        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20746                != PackageManager.PERMISSION_GRANTED) {
20747            String msg = "Permission Denial: isUserRunning() from pid="
20748                    + Binder.getCallingPid()
20749                    + ", uid=" + Binder.getCallingUid()
20750                    + " requires " + INTERACT_ACROSS_USERS;
20751            Slog.w(TAG, msg);
20752            throw new SecurityException(msg);
20753        }
20754        synchronized (this) {
20755            return mUserController.getStartedUserArrayLocked();
20756        }
20757    }
20758
20759    @Override
20760    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20761        mUserController.registerUserSwitchObserver(observer);
20762    }
20763
20764    @Override
20765    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20766        mUserController.unregisterUserSwitchObserver(observer);
20767    }
20768
20769    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20770        if (info == null) return null;
20771        ApplicationInfo newInfo = new ApplicationInfo(info);
20772        newInfo.initForUser(userId);
20773        return newInfo;
20774    }
20775
20776    public boolean isUserStopped(int userId) {
20777        synchronized (this) {
20778            return mUserController.getStartedUserStateLocked(userId) == null;
20779        }
20780    }
20781
20782    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20783        if (aInfo == null
20784                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20785            return aInfo;
20786        }
20787
20788        ActivityInfo info = new ActivityInfo(aInfo);
20789        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20790        return info;
20791    }
20792
20793    private boolean processSanityChecksLocked(ProcessRecord process) {
20794        if (process == null || process.thread == null) {
20795            return false;
20796        }
20797
20798        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20799        if (!isDebuggable) {
20800            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20801                return false;
20802            }
20803        }
20804
20805        return true;
20806    }
20807
20808    public boolean startBinderTracking() throws RemoteException {
20809        synchronized (this) {
20810            mBinderTransactionTrackingEnabled = true;
20811            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20812            // permission (same as profileControl).
20813            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20814                    != PackageManager.PERMISSION_GRANTED) {
20815                throw new SecurityException("Requires permission "
20816                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20817            }
20818
20819            for (int i = 0; i < mLruProcesses.size(); i++) {
20820                ProcessRecord process = mLruProcesses.get(i);
20821                if (!processSanityChecksLocked(process)) {
20822                    continue;
20823                }
20824                try {
20825                    process.thread.startBinderTracking();
20826                } catch (RemoteException e) {
20827                    Log.v(TAG, "Process disappared");
20828                }
20829            }
20830            return true;
20831        }
20832    }
20833
20834    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20835        try {
20836            synchronized (this) {
20837                mBinderTransactionTrackingEnabled = false;
20838                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20839                // permission (same as profileControl).
20840                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20841                        != PackageManager.PERMISSION_GRANTED) {
20842                    throw new SecurityException("Requires permission "
20843                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20844                }
20845
20846                if (fd == null) {
20847                    throw new IllegalArgumentException("null fd");
20848                }
20849
20850                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20851                pw.println("Binder transaction traces for all processes.\n");
20852                for (ProcessRecord process : mLruProcesses) {
20853                    if (!processSanityChecksLocked(process)) {
20854                        continue;
20855                    }
20856
20857                    pw.println("Traces for process: " + process.processName);
20858                    pw.flush();
20859                    try {
20860                        TransferPipe tp = new TransferPipe();
20861                        try {
20862                            process.thread.stopBinderTrackingAndDump(
20863                                    tp.getWriteFd().getFileDescriptor());
20864                            tp.go(fd.getFileDescriptor());
20865                        } finally {
20866                            tp.kill();
20867                        }
20868                    } catch (IOException e) {
20869                        pw.println("Failure while dumping IPC traces from " + process +
20870                                ".  Exception: " + e);
20871                        pw.flush();
20872                    } catch (RemoteException e) {
20873                        pw.println("Got a RemoteException while dumping IPC traces from " +
20874                                process + ".  Exception: " + e);
20875                        pw.flush();
20876                    }
20877                }
20878                fd = null;
20879                return true;
20880            }
20881        } finally {
20882            if (fd != null) {
20883                try {
20884                    fd.close();
20885                } catch (IOException e) {
20886                }
20887            }
20888        }
20889    }
20890
20891    private final class LocalService extends ActivityManagerInternal {
20892        @Override
20893        public void onWakefulnessChanged(int wakefulness) {
20894            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20895        }
20896
20897        @Override
20898        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20899                String processName, String abiOverride, int uid, Runnable crashHandler) {
20900            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20901                    processName, abiOverride, uid, crashHandler);
20902        }
20903
20904        @Override
20905        public SleepToken acquireSleepToken(String tag) {
20906            Preconditions.checkNotNull(tag);
20907
20908            synchronized (ActivityManagerService.this) {
20909                SleepTokenImpl token = new SleepTokenImpl(tag);
20910                mSleepTokens.add(token);
20911                updateSleepIfNeededLocked();
20912                applyVrModeIfNeededLocked(mFocusedActivity, false);
20913                return token;
20914            }
20915        }
20916
20917        @Override
20918        public ComponentName getHomeActivityForUser(int userId) {
20919            synchronized (ActivityManagerService.this) {
20920                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20921                return homeActivity == null ? null : homeActivity.realActivity;
20922            }
20923        }
20924
20925        @Override
20926        public void onUserRemoved(int userId) {
20927            synchronized (ActivityManagerService.this) {
20928                ActivityManagerService.this.onUserStoppedLocked(userId);
20929            }
20930        }
20931
20932        @Override
20933        public void onLocalVoiceInteractionStarted(IBinder activity,
20934                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20935            synchronized (ActivityManagerService.this) {
20936                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20937                        voiceSession, voiceInteractor);
20938            }
20939        }
20940
20941        @Override
20942        public void notifyStartingWindowDrawn() {
20943            synchronized (ActivityManagerService.this) {
20944                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20945            }
20946        }
20947
20948        @Override
20949        public void notifyAppTransitionStarting(int reason) {
20950            synchronized (ActivityManagerService.this) {
20951                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20952            }
20953        }
20954
20955        @Override
20956        public void notifyAppTransitionFinished() {
20957            synchronized (ActivityManagerService.this) {
20958                mStackSupervisor.notifyAppTransitionDone();
20959            }
20960        }
20961
20962        @Override
20963        public void notifyAppTransitionCancelled() {
20964            synchronized (ActivityManagerService.this) {
20965                mStackSupervisor.notifyAppTransitionDone();
20966            }
20967        }
20968
20969        @Override
20970        public List<IBinder> getTopVisibleActivities() {
20971            synchronized (ActivityManagerService.this) {
20972                return mStackSupervisor.getTopVisibleActivities();
20973            }
20974        }
20975
20976        @Override
20977        public void notifyDockedStackMinimizedChanged(boolean minimized) {
20978            synchronized (ActivityManagerService.this) {
20979                mStackSupervisor.setDockedStackMinimized(minimized);
20980            }
20981        }
20982    }
20983
20984    private final class SleepTokenImpl extends SleepToken {
20985        private final String mTag;
20986        private final long mAcquireTime;
20987
20988        public SleepTokenImpl(String tag) {
20989            mTag = tag;
20990            mAcquireTime = SystemClock.uptimeMillis();
20991        }
20992
20993        @Override
20994        public void release() {
20995            synchronized (ActivityManagerService.this) {
20996                if (mSleepTokens.remove(this)) {
20997                    updateSleepIfNeededLocked();
20998                }
20999            }
21000        }
21001
21002        @Override
21003        public String toString() {
21004            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21005        }
21006    }
21007
21008    /**
21009     * An implementation of IAppTask, that allows an app to manage its own tasks via
21010     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21011     * only the process that calls getAppTasks() can call the AppTask methods.
21012     */
21013    class AppTaskImpl extends IAppTask.Stub {
21014        private int mTaskId;
21015        private int mCallingUid;
21016
21017        public AppTaskImpl(int taskId, int callingUid) {
21018            mTaskId = taskId;
21019            mCallingUid = callingUid;
21020        }
21021
21022        private void checkCaller() {
21023            if (mCallingUid != Binder.getCallingUid()) {
21024                throw new SecurityException("Caller " + mCallingUid
21025                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21026            }
21027        }
21028
21029        @Override
21030        public void finishAndRemoveTask() {
21031            checkCaller();
21032
21033            synchronized (ActivityManagerService.this) {
21034                long origId = Binder.clearCallingIdentity();
21035                try {
21036                    // We remove the task from recents to preserve backwards
21037                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21038                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21039                    }
21040                } finally {
21041                    Binder.restoreCallingIdentity(origId);
21042                }
21043            }
21044        }
21045
21046        @Override
21047        public ActivityManager.RecentTaskInfo getTaskInfo() {
21048            checkCaller();
21049
21050            synchronized (ActivityManagerService.this) {
21051                long origId = Binder.clearCallingIdentity();
21052                try {
21053                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21054                    if (tr == null) {
21055                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21056                    }
21057                    return createRecentTaskInfoFromTaskRecord(tr);
21058                } finally {
21059                    Binder.restoreCallingIdentity(origId);
21060                }
21061            }
21062        }
21063
21064        @Override
21065        public void moveToFront() {
21066            checkCaller();
21067            // Will bring task to front if it already has a root activity.
21068            final long origId = Binder.clearCallingIdentity();
21069            try {
21070                synchronized (this) {
21071                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21072                }
21073            } finally {
21074                Binder.restoreCallingIdentity(origId);
21075            }
21076        }
21077
21078        @Override
21079        public int startActivity(IBinder whoThread, String callingPackage,
21080                Intent intent, String resolvedType, Bundle bOptions) {
21081            checkCaller();
21082
21083            int callingUser = UserHandle.getCallingUserId();
21084            TaskRecord tr;
21085            IApplicationThread appThread;
21086            synchronized (ActivityManagerService.this) {
21087                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21088                if (tr == null) {
21089                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21090                }
21091                appThread = ApplicationThreadNative.asInterface(whoThread);
21092                if (appThread == null) {
21093                    throw new IllegalArgumentException("Bad app thread " + appThread);
21094                }
21095            }
21096            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21097                    resolvedType, null, null, null, null, 0, 0, null, null,
21098                    null, bOptions, false, callingUser, null, tr);
21099        }
21100
21101        @Override
21102        public void setExcludeFromRecents(boolean exclude) {
21103            checkCaller();
21104
21105            synchronized (ActivityManagerService.this) {
21106                long origId = Binder.clearCallingIdentity();
21107                try {
21108                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21109                    if (tr == null) {
21110                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21111                    }
21112                    Intent intent = tr.getBaseIntent();
21113                    if (exclude) {
21114                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21115                    } else {
21116                        intent.setFlags(intent.getFlags()
21117                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21118                    }
21119                } finally {
21120                    Binder.restoreCallingIdentity(origId);
21121                }
21122            }
21123        }
21124    }
21125
21126    /**
21127     * Kill processes for the user with id userId and that depend on the package named packageName
21128     */
21129    @Override
21130    public void killPackageDependents(String packageName, int userId) {
21131        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21132        if (packageName == null) {
21133            throw new NullPointerException(
21134                    "Cannot kill the dependents of a package without its name.");
21135        }
21136
21137        long callingId = Binder.clearCallingIdentity();
21138        IPackageManager pm = AppGlobals.getPackageManager();
21139        int pkgUid = -1;
21140        try {
21141            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21142        } catch (RemoteException e) {
21143        }
21144        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21145            throw new IllegalArgumentException(
21146                    "Cannot kill dependents of non-existing package " + packageName);
21147        }
21148        try {
21149            synchronized(this) {
21150                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21151                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21152                        "dep: " + packageName);
21153            }
21154        } finally {
21155            Binder.restoreCallingIdentity(callingId);
21156        }
21157    }
21158}
21159