ActivityManagerService.java revision 514316e76c8869557d3581a318a6bc1497c21851
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            checkTime(startTime, "startProcess: building log message");
3688            StringBuilder buf = mStringBuilder;
3689            buf.setLength(0);
3690            buf.append("Start proc ");
3691            buf.append(startResult.pid);
3692            buf.append(':');
3693            buf.append(app.processName);
3694            buf.append('/');
3695            UserHandle.formatUid(buf, uid);
3696            if (!isActivityProcess) {
3697                buf.append(" [");
3698                buf.append(entryPoint);
3699                buf.append("]");
3700            }
3701            buf.append(" for ");
3702            buf.append(hostingType);
3703            if (hostingNameStr != null) {
3704                buf.append(" ");
3705                buf.append(hostingNameStr);
3706            }
3707            Slog.i(TAG, buf.toString());
3708            app.setPid(startResult.pid);
3709            app.usingWrapper = startResult.usingWrapper;
3710            app.removed = false;
3711            app.killed = false;
3712            app.killedByAm = false;
3713            checkTime(startTime, "startProcess: starting to update pids map");
3714            synchronized (mPidsSelfLocked) {
3715                this.mPidsSelfLocked.put(startResult.pid, app);
3716                if (isActivityProcess) {
3717                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3718                    msg.obj = app;
3719                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3720                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3721                }
3722            }
3723            checkTime(startTime, "startProcess: done updating pids map");
3724        } catch (RuntimeException e) {
3725            // XXX do better error recovery.
3726            app.setPid(0);
3727            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3728            if (app.isolated) {
3729                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3730            }
3731            Slog.e(TAG, "Failure starting process " + app.processName, e);
3732        }
3733    }
3734
3735    void updateUsageStats(ActivityRecord component, boolean resumed) {
3736        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3737                "updateUsageStats: comp=" + component + "res=" + resumed);
3738        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3739        if (resumed) {
3740            if (mUsageStatsService != null) {
3741                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3742                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3743            }
3744            synchronized (stats) {
3745                stats.noteActivityResumedLocked(component.app.uid);
3746            }
3747        } else {
3748            if (mUsageStatsService != null) {
3749                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3750                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3751            }
3752            synchronized (stats) {
3753                stats.noteActivityPausedLocked(component.app.uid);
3754            }
3755        }
3756    }
3757
3758    Intent getHomeIntent() {
3759        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3760        intent.setComponent(mTopComponent);
3761        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3762        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3763            intent.addCategory(Intent.CATEGORY_HOME);
3764        }
3765        return intent;
3766    }
3767
3768    boolean startHomeActivityLocked(int userId, String reason) {
3769        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3770                && mTopAction == null) {
3771            // We are running in factory test mode, but unable to find
3772            // the factory test app, so just sit around displaying the
3773            // error message and don't try to start anything.
3774            return false;
3775        }
3776        Intent intent = getHomeIntent();
3777        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3778        if (aInfo != null) {
3779            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3780            // Don't do this if the home app is currently being
3781            // instrumented.
3782            aInfo = new ActivityInfo(aInfo);
3783            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3784            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3785                    aInfo.applicationInfo.uid, true);
3786            if (app == null || app.instrumentationClass == null) {
3787                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3788                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3789            }
3790        }
3791
3792        return true;
3793    }
3794
3795    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3796        ActivityInfo ai = null;
3797        ComponentName comp = intent.getComponent();
3798        try {
3799            if (comp != null) {
3800                // Factory test.
3801                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3802            } else {
3803                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3804                        intent,
3805                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3806                        flags, userId);
3807
3808                if (info != null) {
3809                    ai = info.activityInfo;
3810                }
3811            }
3812        } catch (RemoteException e) {
3813            // ignore
3814        }
3815
3816        return ai;
3817    }
3818
3819    /**
3820     * Starts the "new version setup screen" if appropriate.
3821     */
3822    void startSetupActivityLocked() {
3823        // Only do this once per boot.
3824        if (mCheckedForSetup) {
3825            return;
3826        }
3827
3828        // We will show this screen if the current one is a different
3829        // version than the last one shown, and we are not running in
3830        // low-level factory test mode.
3831        final ContentResolver resolver = mContext.getContentResolver();
3832        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3833                Settings.Global.getInt(resolver,
3834                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3835            mCheckedForSetup = true;
3836
3837            // See if we should be showing the platform update setup UI.
3838            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3839            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3840                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3841            if (!ris.isEmpty()) {
3842                final ResolveInfo ri = ris.get(0);
3843                String vers = ri.activityInfo.metaData != null
3844                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3845                        : null;
3846                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3847                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3848                            Intent.METADATA_SETUP_VERSION);
3849                }
3850                String lastVers = Settings.Secure.getString(
3851                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3852                if (vers != null && !vers.equals(lastVers)) {
3853                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3854                    intent.setComponent(new ComponentName(
3855                            ri.activityInfo.packageName, ri.activityInfo.name));
3856                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3857                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3858                            null, 0, 0, 0, null, false, false, null, null, null);
3859                }
3860            }
3861        }
3862    }
3863
3864    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3865        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3866    }
3867
3868    void enforceNotIsolatedCaller(String caller) {
3869        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3870            throw new SecurityException("Isolated process not allowed to call " + caller);
3871        }
3872    }
3873
3874    void enforceShellRestriction(String restriction, int userHandle) {
3875        if (Binder.getCallingUid() == Process.SHELL_UID) {
3876            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3877                throw new SecurityException("Shell does not have permission to access user "
3878                        + userHandle);
3879            }
3880        }
3881    }
3882
3883    @Override
3884    public int getFrontActivityScreenCompatMode() {
3885        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3886        synchronized (this) {
3887            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3888        }
3889    }
3890
3891    @Override
3892    public void setFrontActivityScreenCompatMode(int mode) {
3893        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3894                "setFrontActivityScreenCompatMode");
3895        synchronized (this) {
3896            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3897        }
3898    }
3899
3900    @Override
3901    public int getPackageScreenCompatMode(String packageName) {
3902        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3903        synchronized (this) {
3904            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3905        }
3906    }
3907
3908    @Override
3909    public void setPackageScreenCompatMode(String packageName, int mode) {
3910        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3911                "setPackageScreenCompatMode");
3912        synchronized (this) {
3913            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3914        }
3915    }
3916
3917    @Override
3918    public boolean getPackageAskScreenCompat(String packageName) {
3919        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3920        synchronized (this) {
3921            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3922        }
3923    }
3924
3925    @Override
3926    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3927        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3928                "setPackageAskScreenCompat");
3929        synchronized (this) {
3930            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3931        }
3932    }
3933
3934    private boolean hasUsageStatsPermission(String callingPackage) {
3935        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3936                Binder.getCallingUid(), callingPackage);
3937        if (mode == AppOpsManager.MODE_DEFAULT) {
3938            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3939                    == PackageManager.PERMISSION_GRANTED;
3940        }
3941        return mode == AppOpsManager.MODE_ALLOWED;
3942    }
3943
3944    @Override
3945    public int getPackageProcessState(String packageName, String callingPackage) {
3946        if (!hasUsageStatsPermission(callingPackage)) {
3947            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3948                    "getPackageProcessState");
3949        }
3950
3951        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3952        synchronized (this) {
3953            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3954                final ProcessRecord proc = mLruProcesses.get(i);
3955                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3956                        || procState > proc.setProcState) {
3957                    boolean found = false;
3958                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3959                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3960                            procState = proc.setProcState;
3961                            found = true;
3962                        }
3963                    }
3964                    if (proc.pkgDeps != null && !found) {
3965                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3966                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3967                                procState = proc.setProcState;
3968                                break;
3969                            }
3970                        }
3971                    }
3972                }
3973            }
3974        }
3975        return procState;
3976    }
3977
3978    @Override
3979    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3980        synchronized (this) {
3981            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3982            if (app == null) {
3983                return false;
3984            }
3985            if (app.trimMemoryLevel < level && app.thread != null &&
3986                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3987                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3988                try {
3989                    app.thread.scheduleTrimMemory(level);
3990                    app.trimMemoryLevel = level;
3991                    return true;
3992                } catch (RemoteException e) {
3993                    // Fallthrough to failure case.
3994                }
3995            }
3996        }
3997        return false;
3998    }
3999
4000    private void dispatchProcessesChanged() {
4001        int N;
4002        synchronized (this) {
4003            N = mPendingProcessChanges.size();
4004            if (mActiveProcessChanges.length < N) {
4005                mActiveProcessChanges = new ProcessChangeItem[N];
4006            }
4007            mPendingProcessChanges.toArray(mActiveProcessChanges);
4008            mPendingProcessChanges.clear();
4009            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4010                    "*** Delivering " + N + " process changes");
4011        }
4012
4013        int i = mProcessObservers.beginBroadcast();
4014        while (i > 0) {
4015            i--;
4016            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4017            if (observer != null) {
4018                try {
4019                    for (int j=0; j<N; j++) {
4020                        ProcessChangeItem item = mActiveProcessChanges[j];
4021                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4022                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4023                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4024                                    + item.uid + ": " + item.foregroundActivities);
4025                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4026                                    item.foregroundActivities);
4027                        }
4028                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4029                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4030                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4031                                    + ": " + item.processState);
4032                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4033                        }
4034                    }
4035                } catch (RemoteException e) {
4036                }
4037            }
4038        }
4039        mProcessObservers.finishBroadcast();
4040
4041        synchronized (this) {
4042            for (int j=0; j<N; j++) {
4043                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4044            }
4045        }
4046    }
4047
4048    private void dispatchProcessDied(int pid, int uid) {
4049        int i = mProcessObservers.beginBroadcast();
4050        while (i > 0) {
4051            i--;
4052            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4053            if (observer != null) {
4054                try {
4055                    observer.onProcessDied(pid, uid);
4056                } catch (RemoteException e) {
4057                }
4058            }
4059        }
4060        mProcessObservers.finishBroadcast();
4061    }
4062
4063    private void dispatchUidsChanged() {
4064        int N;
4065        synchronized (this) {
4066            N = mPendingUidChanges.size();
4067            if (mActiveUidChanges.length < N) {
4068                mActiveUidChanges = new UidRecord.ChangeItem[N];
4069            }
4070            for (int i=0; i<N; i++) {
4071                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4072                mActiveUidChanges[i] = change;
4073                if (change.uidRecord != null) {
4074                    change.uidRecord.pendingChange = null;
4075                    change.uidRecord = null;
4076                }
4077            }
4078            mPendingUidChanges.clear();
4079            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4080                    "*** Delivering " + N + " uid changes");
4081        }
4082
4083        if (mLocalPowerManager != null) {
4084            for (int j=0; j<N; j++) {
4085                UidRecord.ChangeItem item = mActiveUidChanges[j];
4086                if (item.change == UidRecord.CHANGE_GONE
4087                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4088                    mLocalPowerManager.uidGone(item.uid);
4089                } else {
4090                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4091                }
4092            }
4093        }
4094
4095        int i = mUidObservers.beginBroadcast();
4096        while (i > 0) {
4097            i--;
4098            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4099            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4100            if (observer != null) {
4101                try {
4102                    for (int j=0; j<N; j++) {
4103                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4104                        final int change = item.change;
4105                        UidRecord validateUid = null;
4106                        if (VALIDATE_UID_STATES && i == 0) {
4107                            validateUid = mValidateUids.get(item.uid);
4108                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4109                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4110                                validateUid = new UidRecord(item.uid);
4111                                mValidateUids.put(item.uid, validateUid);
4112                            }
4113                        }
4114                        if (change == UidRecord.CHANGE_IDLE
4115                                || change == UidRecord.CHANGE_GONE_IDLE) {
4116                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4117                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4118                                        "UID idle uid=" + item.uid);
4119                                observer.onUidIdle(item.uid);
4120                            }
4121                            if (VALIDATE_UID_STATES && i == 0) {
4122                                if (validateUid != null) {
4123                                    validateUid.idle = true;
4124                                }
4125                            }
4126                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4127                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4128                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4129                                        "UID active uid=" + item.uid);
4130                                observer.onUidActive(item.uid);
4131                            }
4132                            if (VALIDATE_UID_STATES && i == 0) {
4133                                validateUid.idle = false;
4134                            }
4135                        }
4136                        if (change == UidRecord.CHANGE_GONE
4137                                || change == UidRecord.CHANGE_GONE_IDLE) {
4138                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4139                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4140                                        "UID gone uid=" + item.uid);
4141                                observer.onUidGone(item.uid);
4142                            }
4143                            if (VALIDATE_UID_STATES && i == 0) {
4144                                if (validateUid != null) {
4145                                    mValidateUids.remove(item.uid);
4146                                }
4147                            }
4148                        } else {
4149                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4150                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4151                                        "UID CHANGED uid=" + item.uid
4152                                                + ": " + item.processState);
4153                                observer.onUidStateChanged(item.uid, item.processState);
4154                            }
4155                            if (VALIDATE_UID_STATES && i == 0) {
4156                                validateUid.curProcState = validateUid.setProcState
4157                                        = item.processState;
4158                            }
4159                        }
4160                    }
4161                } catch (RemoteException e) {
4162                }
4163            }
4164        }
4165        mUidObservers.finishBroadcast();
4166
4167        synchronized (this) {
4168            for (int j=0; j<N; j++) {
4169                mAvailUidChanges.add(mActiveUidChanges[j]);
4170            }
4171        }
4172    }
4173
4174    @Override
4175    public final int startActivity(IApplicationThread caller, String callingPackage,
4176            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4177            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4178        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4179                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4180                UserHandle.getCallingUserId());
4181    }
4182
4183    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4184        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4185        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4186                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4187                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4188
4189        // TODO: Switch to user app stacks here.
4190        String mimeType = intent.getType();
4191        final Uri data = intent.getData();
4192        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4193            mimeType = getProviderMimeType(data, userId);
4194        }
4195        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4196
4197        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4198        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4199                null, 0, 0, null, null, null, null, false, userId, container, null);
4200    }
4201
4202    @Override
4203    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4204            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4205            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4206        enforceNotIsolatedCaller("startActivity");
4207        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4208                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4209        // TODO: Switch to user app stacks here.
4210        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4211                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4212                profilerInfo, null, null, bOptions, false, userId, null, null);
4213    }
4214
4215    @Override
4216    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4217            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4218            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4219            int userId) {
4220
4221        // This is very dangerous -- it allows you to perform a start activity (including
4222        // permission grants) as any app that may launch one of your own activities.  So
4223        // we will only allow this to be done from activities that are part of the core framework,
4224        // and then only when they are running as the system.
4225        final ActivityRecord sourceRecord;
4226        final int targetUid;
4227        final String targetPackage;
4228        synchronized (this) {
4229            if (resultTo == null) {
4230                throw new SecurityException("Must be called from an activity");
4231            }
4232            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4233            if (sourceRecord == null) {
4234                throw new SecurityException("Called with bad activity token: " + resultTo);
4235            }
4236            if (!sourceRecord.info.packageName.equals("android")) {
4237                throw new SecurityException(
4238                        "Must be called from an activity that is declared in the android package");
4239            }
4240            if (sourceRecord.app == null) {
4241                throw new SecurityException("Called without a process attached to activity");
4242            }
4243            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4244                // This is still okay, as long as this activity is running under the
4245                // uid of the original calling activity.
4246                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4247                    throw new SecurityException(
4248                            "Calling activity in uid " + sourceRecord.app.uid
4249                                    + " must be system uid or original calling uid "
4250                                    + sourceRecord.launchedFromUid);
4251                }
4252            }
4253            if (ignoreTargetSecurity) {
4254                if (intent.getComponent() == null) {
4255                    throw new SecurityException(
4256                            "Component must be specified with ignoreTargetSecurity");
4257                }
4258                if (intent.getSelector() != null) {
4259                    throw new SecurityException(
4260                            "Selector not allowed with ignoreTargetSecurity");
4261                }
4262            }
4263            targetUid = sourceRecord.launchedFromUid;
4264            targetPackage = sourceRecord.launchedFromPackage;
4265        }
4266
4267        if (userId == UserHandle.USER_NULL) {
4268            userId = UserHandle.getUserId(sourceRecord.app.uid);
4269        }
4270
4271        // TODO: Switch to user app stacks here.
4272        try {
4273            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4274                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4275                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4276            return ret;
4277        } catch (SecurityException e) {
4278            // XXX need to figure out how to propagate to original app.
4279            // A SecurityException here is generally actually a fault of the original
4280            // calling activity (such as a fairly granting permissions), so propagate it
4281            // back to them.
4282            /*
4283            StringBuilder msg = new StringBuilder();
4284            msg.append("While launching");
4285            msg.append(intent.toString());
4286            msg.append(": ");
4287            msg.append(e.getMessage());
4288            */
4289            throw e;
4290        }
4291    }
4292
4293    @Override
4294    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4295            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4296            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4297        enforceNotIsolatedCaller("startActivityAndWait");
4298        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4299                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4300        WaitResult res = new WaitResult();
4301        // TODO: Switch to user app stacks here.
4302        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4303                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4304                bOptions, false, userId, null, null);
4305        return res;
4306    }
4307
4308    @Override
4309    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4310            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4311            int startFlags, Configuration config, Bundle bOptions, int userId) {
4312        enforceNotIsolatedCaller("startActivityWithConfig");
4313        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4314                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4315        // TODO: Switch to user app stacks here.
4316        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4317                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4318                null, null, config, bOptions, false, userId, null, null);
4319        return ret;
4320    }
4321
4322    @Override
4323    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4324            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4325            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4326            throws TransactionTooLargeException {
4327        enforceNotIsolatedCaller("startActivityIntentSender");
4328        // Refuse possible leaked file descriptors
4329        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4330            throw new IllegalArgumentException("File descriptors passed in Intent");
4331        }
4332
4333        IIntentSender sender = intent.getTarget();
4334        if (!(sender instanceof PendingIntentRecord)) {
4335            throw new IllegalArgumentException("Bad PendingIntent object");
4336        }
4337
4338        PendingIntentRecord pir = (PendingIntentRecord)sender;
4339
4340        synchronized (this) {
4341            // If this is coming from the currently resumed activity, it is
4342            // effectively saying that app switches are allowed at this point.
4343            final ActivityStack stack = getFocusedStack();
4344            if (stack.mResumedActivity != null &&
4345                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4346                mAppSwitchesAllowedTime = 0;
4347            }
4348        }
4349        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4350                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4351        return ret;
4352    }
4353
4354    @Override
4355    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4356            Intent intent, String resolvedType, IVoiceInteractionSession session,
4357            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4358            Bundle bOptions, int userId) {
4359        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4360                != PackageManager.PERMISSION_GRANTED) {
4361            String msg = "Permission Denial: startVoiceActivity() from pid="
4362                    + Binder.getCallingPid()
4363                    + ", uid=" + Binder.getCallingUid()
4364                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4365            Slog.w(TAG, msg);
4366            throw new SecurityException(msg);
4367        }
4368        if (session == null || interactor == null) {
4369            throw new NullPointerException("null session or interactor");
4370        }
4371        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4372                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4373        // TODO: Switch to user app stacks here.
4374        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4375                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4376                null, bOptions, false, userId, null, null);
4377    }
4378
4379    @Override
4380    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4381            throws RemoteException {
4382        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4383        synchronized (this) {
4384            ActivityRecord activity = getFocusedStack().topActivity();
4385            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4386                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4387            }
4388            if (mRunningVoice != null || activity.task.voiceSession != null
4389                    || activity.voiceSession != null) {
4390                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4391                return;
4392            }
4393            if (activity.pendingVoiceInteractionStart) {
4394                Slog.w(TAG, "Pending start of voice interaction already.");
4395                return;
4396            }
4397            activity.pendingVoiceInteractionStart = true;
4398        }
4399        LocalServices.getService(VoiceInteractionManagerInternal.class)
4400                .startLocalVoiceInteraction(callingActivity, options);
4401    }
4402
4403    @Override
4404    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4405        LocalServices.getService(VoiceInteractionManagerInternal.class)
4406                .stopLocalVoiceInteraction(callingActivity);
4407    }
4408
4409    @Override
4410    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4411        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4412                .supportsLocalVoiceInteraction();
4413    }
4414
4415    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4416            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4417        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4418        if (activityToCallback == null) return;
4419        activityToCallback.setVoiceSessionLocked(voiceSession);
4420
4421        // Inform the activity
4422        try {
4423            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4424                    voiceInteractor);
4425            long token = Binder.clearCallingIdentity();
4426            try {
4427                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4428            } finally {
4429                Binder.restoreCallingIdentity(token);
4430            }
4431            // TODO: VI Should we cache the activity so that it's easier to find later
4432            // rather than scan through all the stacks and activities?
4433        } catch (RemoteException re) {
4434            activityToCallback.clearVoiceSessionLocked();
4435            // TODO: VI Should this terminate the voice session?
4436        }
4437    }
4438
4439    @Override
4440    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4441        synchronized (this) {
4442            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4443                if (keepAwake) {
4444                    mVoiceWakeLock.acquire();
4445                } else {
4446                    mVoiceWakeLock.release();
4447                }
4448            }
4449        }
4450    }
4451
4452    @Override
4453    public boolean startNextMatchingActivity(IBinder callingActivity,
4454            Intent intent, Bundle bOptions) {
4455        // Refuse possible leaked file descriptors
4456        if (intent != null && intent.hasFileDescriptors() == true) {
4457            throw new IllegalArgumentException("File descriptors passed in Intent");
4458        }
4459        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4460
4461        synchronized (this) {
4462            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4463            if (r == null) {
4464                ActivityOptions.abort(options);
4465                return false;
4466            }
4467            if (r.app == null || r.app.thread == null) {
4468                // The caller is not running...  d'oh!
4469                ActivityOptions.abort(options);
4470                return false;
4471            }
4472            intent = new Intent(intent);
4473            // The caller is not allowed to change the data.
4474            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4475            // And we are resetting to find the next component...
4476            intent.setComponent(null);
4477
4478            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4479
4480            ActivityInfo aInfo = null;
4481            try {
4482                List<ResolveInfo> resolves =
4483                    AppGlobals.getPackageManager().queryIntentActivities(
4484                            intent, r.resolvedType,
4485                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4486                            UserHandle.getCallingUserId()).getList();
4487
4488                // Look for the original activity in the list...
4489                final int N = resolves != null ? resolves.size() : 0;
4490                for (int i=0; i<N; i++) {
4491                    ResolveInfo rInfo = resolves.get(i);
4492                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4493                            && rInfo.activityInfo.name.equals(r.info.name)) {
4494                        // We found the current one...  the next matching is
4495                        // after it.
4496                        i++;
4497                        if (i<N) {
4498                            aInfo = resolves.get(i).activityInfo;
4499                        }
4500                        if (debug) {
4501                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4502                                    + "/" + r.info.name);
4503                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4504                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4505                        }
4506                        break;
4507                    }
4508                }
4509            } catch (RemoteException e) {
4510            }
4511
4512            if (aInfo == null) {
4513                // Nobody who is next!
4514                ActivityOptions.abort(options);
4515                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4516                return false;
4517            }
4518
4519            intent.setComponent(new ComponentName(
4520                    aInfo.applicationInfo.packageName, aInfo.name));
4521            intent.setFlags(intent.getFlags()&~(
4522                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4523                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4524                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4525                    Intent.FLAG_ACTIVITY_NEW_TASK));
4526
4527            // Okay now we need to start the new activity, replacing the
4528            // currently running activity.  This is a little tricky because
4529            // we want to start the new one as if the current one is finished,
4530            // but not finish the current one first so that there is no flicker.
4531            // And thus...
4532            final boolean wasFinishing = r.finishing;
4533            r.finishing = true;
4534
4535            // Propagate reply information over to the new activity.
4536            final ActivityRecord resultTo = r.resultTo;
4537            final String resultWho = r.resultWho;
4538            final int requestCode = r.requestCode;
4539            r.resultTo = null;
4540            if (resultTo != null) {
4541                resultTo.removeResultsLocked(r, resultWho, requestCode);
4542            }
4543
4544            final long origId = Binder.clearCallingIdentity();
4545            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4546                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4547                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4548                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4549                    false, false, null, null, null);
4550            Binder.restoreCallingIdentity(origId);
4551
4552            r.finishing = wasFinishing;
4553            if (res != ActivityManager.START_SUCCESS) {
4554                return false;
4555            }
4556            return true;
4557        }
4558    }
4559
4560    @Override
4561    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4562        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4563            String msg = "Permission Denial: startActivityFromRecents called without " +
4564                    START_TASKS_FROM_RECENTS;
4565            Slog.w(TAG, msg);
4566            throw new SecurityException(msg);
4567        }
4568        final long origId = Binder.clearCallingIdentity();
4569        try {
4570            synchronized (this) {
4571                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4572            }
4573        } finally {
4574            Binder.restoreCallingIdentity(origId);
4575        }
4576    }
4577
4578    final int startActivityInPackage(int uid, String callingPackage,
4579            Intent intent, String resolvedType, IBinder resultTo,
4580            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4581            IActivityContainer container, TaskRecord inTask) {
4582
4583        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4584                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4585
4586        // TODO: Switch to user app stacks here.
4587        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4588                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4589                null, null, null, bOptions, false, userId, container, inTask);
4590        return ret;
4591    }
4592
4593    @Override
4594    public final int startActivities(IApplicationThread caller, String callingPackage,
4595            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4596            int userId) {
4597        enforceNotIsolatedCaller("startActivities");
4598        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4599                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4600        // TODO: Switch to user app stacks here.
4601        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4602                resolvedTypes, resultTo, bOptions, userId);
4603        return ret;
4604    }
4605
4606    final int startActivitiesInPackage(int uid, String callingPackage,
4607            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4608            Bundle bOptions, int userId) {
4609
4610        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4611                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4612        // TODO: Switch to user app stacks here.
4613        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4614                resultTo, bOptions, userId);
4615        return ret;
4616    }
4617
4618    @Override
4619    public void reportActivityFullyDrawn(IBinder token) {
4620        synchronized (this) {
4621            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4622            if (r == null) {
4623                return;
4624            }
4625            r.reportFullyDrawnLocked();
4626        }
4627    }
4628
4629    @Override
4630    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4631        synchronized (this) {
4632            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4633            if (r == null) {
4634                return;
4635            }
4636            TaskRecord task = r.task;
4637            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4638                // Fixed screen orientation isn't supported when activities aren't in full screen
4639                // mode.
4640                return;
4641            }
4642            final long origId = Binder.clearCallingIdentity();
4643            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4644            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4645                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4646            if (config != null) {
4647                r.frozenBeforeDestroy = true;
4648                if (!updateConfigurationLocked(config, r, false)) {
4649                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4650                }
4651            }
4652            Binder.restoreCallingIdentity(origId);
4653        }
4654    }
4655
4656    @Override
4657    public int getRequestedOrientation(IBinder token) {
4658        synchronized (this) {
4659            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4660            if (r == null) {
4661                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4662            }
4663            return mWindowManager.getAppOrientation(r.appToken);
4664        }
4665    }
4666
4667    /**
4668     * This is the internal entry point for handling Activity.finish().
4669     *
4670     * @param token The Binder token referencing the Activity we want to finish.
4671     * @param resultCode Result code, if any, from this Activity.
4672     * @param resultData Result data (Intent), if any, from this Activity.
4673     * @param finishTask Whether to finish the task associated with this Activity.
4674     *
4675     * @return Returns true if the activity successfully finished, or false if it is still running.
4676     */
4677    @Override
4678    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4679            int finishTask) {
4680        // Refuse possible leaked file descriptors
4681        if (resultData != null && resultData.hasFileDescriptors() == true) {
4682            throw new IllegalArgumentException("File descriptors passed in Intent");
4683        }
4684
4685        synchronized(this) {
4686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4687            if (r == null) {
4688                return true;
4689            }
4690            // Keep track of the root activity of the task before we finish it
4691            TaskRecord tr = r.task;
4692            ActivityRecord rootR = tr.getRootActivity();
4693            if (rootR == null) {
4694                Slog.w(TAG, "Finishing task with all activities already finished");
4695            }
4696            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4697            // finish.
4698            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4699                    mStackSupervisor.isLastLockedTask(tr)) {
4700                Slog.i(TAG, "Not finishing task in lock task mode");
4701                mStackSupervisor.showLockTaskToast();
4702                return false;
4703            }
4704            if (mController != null) {
4705                // Find the first activity that is not finishing.
4706                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4707                if (next != null) {
4708                    // ask watcher if this is allowed
4709                    boolean resumeOK = true;
4710                    try {
4711                        resumeOK = mController.activityResuming(next.packageName);
4712                    } catch (RemoteException e) {
4713                        mController = null;
4714                        Watchdog.getInstance().setActivityController(null);
4715                    }
4716
4717                    if (!resumeOK) {
4718                        Slog.i(TAG, "Not finishing activity because controller resumed");
4719                        return false;
4720                    }
4721                }
4722            }
4723            final long origId = Binder.clearCallingIdentity();
4724            try {
4725                boolean res;
4726                final boolean finishWithRootActivity =
4727                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4728                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4729                        || (finishWithRootActivity && r == rootR)) {
4730                    // If requested, remove the task that is associated to this activity only if it
4731                    // was the root activity in the task. The result code and data is ignored
4732                    // because we don't support returning them across task boundaries. Also, to
4733                    // keep backwards compatibility we remove the task from recents when finishing
4734                    // task with root activity.
4735                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4736                    if (!res) {
4737                        Slog.i(TAG, "Removing task failed to finish activity");
4738                    }
4739                } else {
4740                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4741                            resultData, "app-request", true);
4742                    if (!res) {
4743                        Slog.i(TAG, "Failed to finish by app-request");
4744                    }
4745                }
4746                return res;
4747            } finally {
4748                Binder.restoreCallingIdentity(origId);
4749            }
4750        }
4751    }
4752
4753    @Override
4754    public final void finishHeavyWeightApp() {
4755        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4756                != PackageManager.PERMISSION_GRANTED) {
4757            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4758                    + Binder.getCallingPid()
4759                    + ", uid=" + Binder.getCallingUid()
4760                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4761            Slog.w(TAG, msg);
4762            throw new SecurityException(msg);
4763        }
4764
4765        synchronized(this) {
4766            if (mHeavyWeightProcess == null) {
4767                return;
4768            }
4769
4770            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4771            for (int i = 0; i < activities.size(); i++) {
4772                ActivityRecord r = activities.get(i);
4773                if (!r.finishing && r.isInStackLocked()) {
4774                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4775                            null, "finish-heavy", true);
4776                }
4777            }
4778
4779            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4780                    mHeavyWeightProcess.userId, 0));
4781            mHeavyWeightProcess = null;
4782        }
4783    }
4784
4785    @Override
4786    public void crashApplication(int uid, int initialPid, String packageName,
4787            String message) {
4788        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4789                != PackageManager.PERMISSION_GRANTED) {
4790            String msg = "Permission Denial: crashApplication() from pid="
4791                    + Binder.getCallingPid()
4792                    + ", uid=" + Binder.getCallingUid()
4793                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4794            Slog.w(TAG, msg);
4795            throw new SecurityException(msg);
4796        }
4797
4798        synchronized(this) {
4799            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4800        }
4801    }
4802
4803    @Override
4804    public final void finishSubActivity(IBinder token, String resultWho,
4805            int requestCode) {
4806        synchronized(this) {
4807            final long origId = Binder.clearCallingIdentity();
4808            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4809            if (r != null) {
4810                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4811            }
4812            Binder.restoreCallingIdentity(origId);
4813        }
4814    }
4815
4816    @Override
4817    public boolean finishActivityAffinity(IBinder token) {
4818        synchronized(this) {
4819            final long origId = Binder.clearCallingIdentity();
4820            try {
4821                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4822                if (r == null) {
4823                    return false;
4824                }
4825
4826                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4827                // can finish.
4828                final TaskRecord task = r.task;
4829                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4830                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4831                    mStackSupervisor.showLockTaskToast();
4832                    return false;
4833                }
4834                return task.stack.finishActivityAffinityLocked(r);
4835            } finally {
4836                Binder.restoreCallingIdentity(origId);
4837            }
4838        }
4839    }
4840
4841    @Override
4842    public void finishVoiceTask(IVoiceInteractionSession session) {
4843        synchronized (this) {
4844            final long origId = Binder.clearCallingIdentity();
4845            try {
4846                // TODO: VI Consider treating local voice interactions and voice tasks
4847                // differently here
4848                mStackSupervisor.finishVoiceTask(session);
4849            } finally {
4850                Binder.restoreCallingIdentity(origId);
4851            }
4852        }
4853
4854    }
4855
4856    @Override
4857    public boolean releaseActivityInstance(IBinder token) {
4858        synchronized(this) {
4859            final long origId = Binder.clearCallingIdentity();
4860            try {
4861                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4862                if (r == null) {
4863                    return false;
4864                }
4865                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4866            } finally {
4867                Binder.restoreCallingIdentity(origId);
4868            }
4869        }
4870    }
4871
4872    @Override
4873    public void releaseSomeActivities(IApplicationThread appInt) {
4874        synchronized(this) {
4875            final long origId = Binder.clearCallingIdentity();
4876            try {
4877                ProcessRecord app = getRecordForAppLocked(appInt);
4878                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4879            } finally {
4880                Binder.restoreCallingIdentity(origId);
4881            }
4882        }
4883    }
4884
4885    @Override
4886    public boolean willActivityBeVisible(IBinder token) {
4887        synchronized(this) {
4888            ActivityStack stack = ActivityRecord.getStackLocked(token);
4889            if (stack != null) {
4890                return stack.willActivityBeVisibleLocked(token);
4891            }
4892            return false;
4893        }
4894    }
4895
4896    @Override
4897    public void overridePendingTransition(IBinder token, String packageName,
4898            int enterAnim, int exitAnim) {
4899        synchronized(this) {
4900            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4901            if (self == null) {
4902                return;
4903            }
4904
4905            final long origId = Binder.clearCallingIdentity();
4906
4907            if (self.state == ActivityState.RESUMED
4908                    || self.state == ActivityState.PAUSING) {
4909                mWindowManager.overridePendingAppTransition(packageName,
4910                        enterAnim, exitAnim, null);
4911            }
4912
4913            Binder.restoreCallingIdentity(origId);
4914        }
4915    }
4916
4917    /**
4918     * Main function for removing an existing process from the activity manager
4919     * as a result of that process going away.  Clears out all connections
4920     * to the process.
4921     */
4922    private final void handleAppDiedLocked(ProcessRecord app,
4923            boolean restarting, boolean allowRestart) {
4924        int pid = app.pid;
4925        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4926        if (!kept && !restarting) {
4927            removeLruProcessLocked(app);
4928            if (pid > 0) {
4929                ProcessList.remove(pid);
4930            }
4931        }
4932
4933        if (mProfileProc == app) {
4934            clearProfilerLocked();
4935        }
4936
4937        // Remove this application's activities from active lists.
4938        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4939
4940        app.activities.clear();
4941
4942        if (app.instrumentationClass != null) {
4943            Slog.w(TAG, "Crash of app " + app.processName
4944                  + " running instrumentation " + app.instrumentationClass);
4945            Bundle info = new Bundle();
4946            info.putString("shortMsg", "Process crashed.");
4947            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4948        }
4949
4950        if (!restarting && hasVisibleActivities
4951                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4952            // If there was nothing to resume, and we are not already restarting this process, but
4953            // there is a visible activity that is hosted by the process...  then make sure all
4954            // visible activities are running, taking care of restarting this process.
4955            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4956        }
4957    }
4958
4959    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4960        IBinder threadBinder = thread.asBinder();
4961        // Find the application record.
4962        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4963            ProcessRecord rec = mLruProcesses.get(i);
4964            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4965                return i;
4966            }
4967        }
4968        return -1;
4969    }
4970
4971    final ProcessRecord getRecordForAppLocked(
4972            IApplicationThread thread) {
4973        if (thread == null) {
4974            return null;
4975        }
4976
4977        int appIndex = getLRURecordIndexForAppLocked(thread);
4978        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4979    }
4980
4981    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4982        // If there are no longer any background processes running,
4983        // and the app that died was not running instrumentation,
4984        // then tell everyone we are now low on memory.
4985        boolean haveBg = false;
4986        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4987            ProcessRecord rec = mLruProcesses.get(i);
4988            if (rec.thread != null
4989                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4990                haveBg = true;
4991                break;
4992            }
4993        }
4994
4995        if (!haveBg) {
4996            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4997            if (doReport) {
4998                long now = SystemClock.uptimeMillis();
4999                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5000                    doReport = false;
5001                } else {
5002                    mLastMemUsageReportTime = now;
5003                }
5004            }
5005            final ArrayList<ProcessMemInfo> memInfos
5006                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5007            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5008            long now = SystemClock.uptimeMillis();
5009            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5010                ProcessRecord rec = mLruProcesses.get(i);
5011                if (rec == dyingProc || rec.thread == null) {
5012                    continue;
5013                }
5014                if (doReport) {
5015                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5016                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5017                }
5018                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5019                    // The low memory report is overriding any current
5020                    // state for a GC request.  Make sure to do
5021                    // heavy/important/visible/foreground processes first.
5022                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5023                        rec.lastRequestedGc = 0;
5024                    } else {
5025                        rec.lastRequestedGc = rec.lastLowMemory;
5026                    }
5027                    rec.reportLowMemory = true;
5028                    rec.lastLowMemory = now;
5029                    mProcessesToGc.remove(rec);
5030                    addProcessToGcListLocked(rec);
5031                }
5032            }
5033            if (doReport) {
5034                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5035                mHandler.sendMessage(msg);
5036            }
5037            scheduleAppGcsLocked();
5038        }
5039    }
5040
5041    final void appDiedLocked(ProcessRecord app) {
5042       appDiedLocked(app, app.pid, app.thread, false);
5043    }
5044
5045    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5046            boolean fromBinderDied) {
5047        // First check if this ProcessRecord is actually active for the pid.
5048        synchronized (mPidsSelfLocked) {
5049            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5050            if (curProc != app) {
5051                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5052                return;
5053            }
5054        }
5055
5056        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5057        synchronized (stats) {
5058            stats.noteProcessDiedLocked(app.info.uid, pid);
5059        }
5060
5061        if (!app.killed) {
5062            if (!fromBinderDied) {
5063                Process.killProcessQuiet(pid);
5064            }
5065            killProcessGroup(app.uid, pid);
5066            app.killed = true;
5067        }
5068
5069        // Clean up already done if the process has been re-started.
5070        if (app.pid == pid && app.thread != null &&
5071                app.thread.asBinder() == thread.asBinder()) {
5072            boolean doLowMem = app.instrumentationClass == null;
5073            boolean doOomAdj = doLowMem;
5074            if (!app.killedByAm) {
5075                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5076                        + ") has died");
5077                mAllowLowerMemLevel = true;
5078            } else {
5079                // Note that we always want to do oom adj to update our state with the
5080                // new number of procs.
5081                mAllowLowerMemLevel = false;
5082                doLowMem = false;
5083            }
5084            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5085            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5086                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5087            handleAppDiedLocked(app, false, true);
5088
5089            if (doOomAdj) {
5090                updateOomAdjLocked();
5091            }
5092            if (doLowMem) {
5093                doLowMemReportIfNeededLocked(app);
5094            }
5095        } else if (app.pid != pid) {
5096            // A new process has already been started.
5097            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5098                    + ") has died and restarted (pid " + app.pid + ").");
5099            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5100        } else if (DEBUG_PROCESSES) {
5101            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5102                    + thread.asBinder());
5103        }
5104    }
5105
5106    /**
5107     * If a stack trace dump file is configured, dump process stack traces.
5108     * @param clearTraces causes the dump file to be erased prior to the new
5109     *    traces being written, if true; when false, the new traces will be
5110     *    appended to any existing file content.
5111     * @param firstPids of dalvik VM processes to dump stack traces for first
5112     * @param lastPids of dalvik VM processes to dump stack traces for last
5113     * @param nativeProcs optional list of native process names to dump stack crawls
5114     * @return file containing stack traces, or null if no dump file is configured
5115     */
5116    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5117            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5118        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5119        if (tracesPath == null || tracesPath.length() == 0) {
5120            return null;
5121        }
5122
5123        File tracesFile = new File(tracesPath);
5124        try {
5125            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5126            tracesFile.createNewFile();
5127            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5128        } catch (IOException e) {
5129            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5130            return null;
5131        }
5132
5133        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5134        return tracesFile;
5135    }
5136
5137    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5138            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5139        // Use a FileObserver to detect when traces finish writing.
5140        // The order of traces is considered important to maintain for legibility.
5141        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5142            @Override
5143            public synchronized void onEvent(int event, String path) { notify(); }
5144        };
5145
5146        try {
5147            observer.startWatching();
5148
5149            // First collect all of the stacks of the most important pids.
5150            if (firstPids != null) {
5151                try {
5152                    int num = firstPids.size();
5153                    for (int i = 0; i < num; i++) {
5154                        synchronized (observer) {
5155                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5156                                    + firstPids.get(i));
5157                            final long sime = SystemClock.elapsedRealtime();
5158                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5159                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5160                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5161                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5162                        }
5163                    }
5164                } catch (InterruptedException e) {
5165                    Slog.wtf(TAG, e);
5166                }
5167            }
5168
5169            // Next collect the stacks of the native pids
5170            if (nativeProcs != null) {
5171                int[] pids = Process.getPidsForCommands(nativeProcs);
5172                if (pids != null) {
5173                    for (int pid : pids) {
5174                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5175                        final long sime = SystemClock.elapsedRealtime();
5176                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5177                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5178                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5179                    }
5180                }
5181            }
5182
5183            // Lastly, measure CPU usage.
5184            if (processCpuTracker != null) {
5185                processCpuTracker.init();
5186                System.gc();
5187                processCpuTracker.update();
5188                try {
5189                    synchronized (processCpuTracker) {
5190                        processCpuTracker.wait(500); // measure over 1/2 second.
5191                    }
5192                } catch (InterruptedException e) {
5193                }
5194                processCpuTracker.update();
5195
5196                // We'll take the stack crawls of just the top apps using CPU.
5197                final int N = processCpuTracker.countWorkingStats();
5198                int numProcs = 0;
5199                for (int i=0; i<N && numProcs<5; i++) {
5200                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5201                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5202                        numProcs++;
5203                        try {
5204                            synchronized (observer) {
5205                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5206                                        + stats.pid);
5207                                final long stime = SystemClock.elapsedRealtime();
5208                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5209                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5210                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5211                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5212                            }
5213                        } catch (InterruptedException e) {
5214                            Slog.wtf(TAG, e);
5215                        }
5216                    } else if (DEBUG_ANR) {
5217                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5218                                + stats.pid);
5219                    }
5220                }
5221            }
5222        } finally {
5223            observer.stopWatching();
5224        }
5225    }
5226
5227    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5228        if (true || IS_USER_BUILD) {
5229            return;
5230        }
5231        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5232        if (tracesPath == null || tracesPath.length() == 0) {
5233            return;
5234        }
5235
5236        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5237        StrictMode.allowThreadDiskWrites();
5238        try {
5239            final File tracesFile = new File(tracesPath);
5240            final File tracesDir = tracesFile.getParentFile();
5241            final File tracesTmp = new File(tracesDir, "__tmp__");
5242            try {
5243                if (tracesFile.exists()) {
5244                    tracesTmp.delete();
5245                    tracesFile.renameTo(tracesTmp);
5246                }
5247                StringBuilder sb = new StringBuilder();
5248                Time tobj = new Time();
5249                tobj.set(System.currentTimeMillis());
5250                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5251                sb.append(": ");
5252                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5253                sb.append(" since ");
5254                sb.append(msg);
5255                FileOutputStream fos = new FileOutputStream(tracesFile);
5256                fos.write(sb.toString().getBytes());
5257                if (app == null) {
5258                    fos.write("\n*** No application process!".getBytes());
5259                }
5260                fos.close();
5261                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5262            } catch (IOException e) {
5263                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5264                return;
5265            }
5266
5267            if (app != null) {
5268                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5269                firstPids.add(app.pid);
5270                dumpStackTraces(tracesPath, firstPids, null, null, null);
5271            }
5272
5273            File lastTracesFile = null;
5274            File curTracesFile = null;
5275            for (int i=9; i>=0; i--) {
5276                String name = String.format(Locale.US, "slow%02d.txt", i);
5277                curTracesFile = new File(tracesDir, name);
5278                if (curTracesFile.exists()) {
5279                    if (lastTracesFile != null) {
5280                        curTracesFile.renameTo(lastTracesFile);
5281                    } else {
5282                        curTracesFile.delete();
5283                    }
5284                }
5285                lastTracesFile = curTracesFile;
5286            }
5287            tracesFile.renameTo(curTracesFile);
5288            if (tracesTmp.exists()) {
5289                tracesTmp.renameTo(tracesFile);
5290            }
5291        } finally {
5292            StrictMode.setThreadPolicy(oldPolicy);
5293        }
5294    }
5295
5296    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5297        if (!mLaunchWarningShown) {
5298            mLaunchWarningShown = true;
5299            mUiHandler.post(new Runnable() {
5300                @Override
5301                public void run() {
5302                    synchronized (ActivityManagerService.this) {
5303                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5304                        d.show();
5305                        mUiHandler.postDelayed(new Runnable() {
5306                            @Override
5307                            public void run() {
5308                                synchronized (ActivityManagerService.this) {
5309                                    d.dismiss();
5310                                    mLaunchWarningShown = false;
5311                                }
5312                            }
5313                        }, 4000);
5314                    }
5315                }
5316            });
5317        }
5318    }
5319
5320    @Override
5321    public boolean clearApplicationUserData(final String packageName,
5322            final IPackageDataObserver observer, int userId) {
5323        enforceNotIsolatedCaller("clearApplicationUserData");
5324        int uid = Binder.getCallingUid();
5325        int pid = Binder.getCallingPid();
5326        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5327                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5328
5329        final DevicePolicyManagerInternal dpmi = LocalServices
5330                .getService(DevicePolicyManagerInternal.class);
5331        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5332            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5333        }
5334
5335        long callingId = Binder.clearCallingIdentity();
5336        try {
5337            IPackageManager pm = AppGlobals.getPackageManager();
5338            int pkgUid = -1;
5339            synchronized(this) {
5340                try {
5341                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5342                } catch (RemoteException e) {
5343                }
5344                if (pkgUid == -1) {
5345                    Slog.w(TAG, "Invalid packageName: " + packageName);
5346                    if (observer != null) {
5347                        try {
5348                            observer.onRemoveCompleted(packageName, false);
5349                        } catch (RemoteException e) {
5350                            Slog.i(TAG, "Observer no longer exists.");
5351                        }
5352                    }
5353                    return false;
5354                }
5355                if (uid == pkgUid || checkComponentPermission(
5356                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5357                        pid, uid, -1, true)
5358                        == PackageManager.PERMISSION_GRANTED) {
5359                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5360                } else {
5361                    throw new SecurityException("PID " + pid + " does not have permission "
5362                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5363                                    + " of package " + packageName);
5364                }
5365
5366                // Remove all tasks match the cleared application package and user
5367                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5368                    final TaskRecord tr = mRecentTasks.get(i);
5369                    final String taskPackageName =
5370                            tr.getBaseIntent().getComponent().getPackageName();
5371                    if (tr.userId != userId) continue;
5372                    if (!taskPackageName.equals(packageName)) continue;
5373                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5374                }
5375            }
5376
5377            try {
5378                // Clear application user data
5379                pm.clearApplicationUserData(packageName, observer, userId);
5380
5381                synchronized(this) {
5382                    // Remove all permissions granted from/to this package
5383                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5384                }
5385
5386                // Remove all zen rules created by this package; revoke it's zen access.
5387                INotificationManager inm = NotificationManager.getService();
5388                inm.removeAutomaticZenRules(packageName);
5389                inm.setNotificationPolicyAccessGranted(packageName, false);
5390
5391                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5392                        Uri.fromParts("package", packageName, null));
5393                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5394                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5395                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5396                        null, null, 0, null, null, null, null, false, false, userId);
5397            } catch (RemoteException e) {
5398            }
5399        } finally {
5400            Binder.restoreCallingIdentity(callingId);
5401        }
5402        return true;
5403    }
5404
5405    @Override
5406    public void killBackgroundProcesses(final String packageName, int userId) {
5407        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5408                != PackageManager.PERMISSION_GRANTED &&
5409                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5410                        != PackageManager.PERMISSION_GRANTED) {
5411            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5412                    + Binder.getCallingPid()
5413                    + ", uid=" + Binder.getCallingUid()
5414                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5415            Slog.w(TAG, msg);
5416            throw new SecurityException(msg);
5417        }
5418
5419        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5420                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5421        long callingId = Binder.clearCallingIdentity();
5422        try {
5423            IPackageManager pm = AppGlobals.getPackageManager();
5424            synchronized(this) {
5425                int appId = -1;
5426                try {
5427                    appId = UserHandle.getAppId(
5428                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5429                } catch (RemoteException e) {
5430                }
5431                if (appId == -1) {
5432                    Slog.w(TAG, "Invalid packageName: " + packageName);
5433                    return;
5434                }
5435                killPackageProcessesLocked(packageName, appId, userId,
5436                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5437            }
5438        } finally {
5439            Binder.restoreCallingIdentity(callingId);
5440        }
5441    }
5442
5443    @Override
5444    public void killAllBackgroundProcesses() {
5445        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5446                != PackageManager.PERMISSION_GRANTED) {
5447            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5448                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5449                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5450            Slog.w(TAG, msg);
5451            throw new SecurityException(msg);
5452        }
5453
5454        final long callingId = Binder.clearCallingIdentity();
5455        try {
5456            synchronized (this) {
5457                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5458                final int NP = mProcessNames.getMap().size();
5459                for (int ip = 0; ip < NP; ip++) {
5460                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5461                    final int NA = apps.size();
5462                    for (int ia = 0; ia < NA; ia++) {
5463                        final ProcessRecord app = apps.valueAt(ia);
5464                        if (app.persistent) {
5465                            // We don't kill persistent processes.
5466                            continue;
5467                        }
5468                        if (app.removed) {
5469                            procs.add(app);
5470                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5471                            app.removed = true;
5472                            procs.add(app);
5473                        }
5474                    }
5475                }
5476
5477                final int N = procs.size();
5478                for (int i = 0; i < N; i++) {
5479                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5480                }
5481
5482                mAllowLowerMemLevel = true;
5483
5484                updateOomAdjLocked();
5485                doLowMemReportIfNeededLocked(null);
5486            }
5487        } finally {
5488            Binder.restoreCallingIdentity(callingId);
5489        }
5490    }
5491
5492    /**
5493     * Kills all background processes, except those matching any of the
5494     * specified properties.
5495     *
5496     * @param minTargetSdk the target SDK version at or above which to preserve
5497     *                     processes, or {@code -1} to ignore the target SDK
5498     * @param maxProcState the process state at or below which to preserve
5499     *                     processes, or {@code -1} to ignore the process state
5500     */
5501    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5502        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5503                != PackageManager.PERMISSION_GRANTED) {
5504            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5505                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5506                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5507            Slog.w(TAG, msg);
5508            throw new SecurityException(msg);
5509        }
5510
5511        final long callingId = Binder.clearCallingIdentity();
5512        try {
5513            synchronized (this) {
5514                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5515                final int NP = mProcessNames.getMap().size();
5516                for (int ip = 0; ip < NP; ip++) {
5517                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5518                    final int NA = apps.size();
5519                    for (int ia = 0; ia < NA; ia++) {
5520                        final ProcessRecord app = apps.valueAt(ia);
5521                        if (app.removed) {
5522                            procs.add(app);
5523                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5524                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5525                            app.removed = true;
5526                            procs.add(app);
5527                        }
5528                    }
5529                }
5530
5531                final int N = procs.size();
5532                for (int i = 0; i < N; i++) {
5533                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5534                }
5535            }
5536        } finally {
5537            Binder.restoreCallingIdentity(callingId);
5538        }
5539    }
5540
5541    @Override
5542    public void forceStopPackage(final String packageName, int userId) {
5543        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5544                != PackageManager.PERMISSION_GRANTED) {
5545            String msg = "Permission Denial: forceStopPackage() from pid="
5546                    + Binder.getCallingPid()
5547                    + ", uid=" + Binder.getCallingUid()
5548                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5549            Slog.w(TAG, msg);
5550            throw new SecurityException(msg);
5551        }
5552        final int callingPid = Binder.getCallingPid();
5553        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5554                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5555        long callingId = Binder.clearCallingIdentity();
5556        try {
5557            IPackageManager pm = AppGlobals.getPackageManager();
5558            synchronized(this) {
5559                int[] users = userId == UserHandle.USER_ALL
5560                        ? mUserController.getUsers() : new int[] { userId };
5561                for (int user : users) {
5562                    int pkgUid = -1;
5563                    try {
5564                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5565                                user);
5566                    } catch (RemoteException e) {
5567                    }
5568                    if (pkgUid == -1) {
5569                        Slog.w(TAG, "Invalid packageName: " + packageName);
5570                        continue;
5571                    }
5572                    try {
5573                        pm.setPackageStoppedState(packageName, true, user);
5574                    } catch (RemoteException e) {
5575                    } catch (IllegalArgumentException e) {
5576                        Slog.w(TAG, "Failed trying to unstop package "
5577                                + packageName + ": " + e);
5578                    }
5579                    if (mUserController.isUserRunningLocked(user, 0)) {
5580                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5581                    }
5582                }
5583            }
5584        } finally {
5585            Binder.restoreCallingIdentity(callingId);
5586        }
5587    }
5588
5589    @Override
5590    public void addPackageDependency(String packageName) {
5591        synchronized (this) {
5592            int callingPid = Binder.getCallingPid();
5593            if (callingPid == Process.myPid()) {
5594                //  Yeah, um, no.
5595                return;
5596            }
5597            ProcessRecord proc;
5598            synchronized (mPidsSelfLocked) {
5599                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5600            }
5601            if (proc != null) {
5602                if (proc.pkgDeps == null) {
5603                    proc.pkgDeps = new ArraySet<String>(1);
5604                }
5605                proc.pkgDeps.add(packageName);
5606            }
5607        }
5608    }
5609
5610    /*
5611     * The pkg name and app id have to be specified.
5612     */
5613    @Override
5614    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5615        if (pkg == null) {
5616            return;
5617        }
5618        // Make sure the uid is valid.
5619        if (appid < 0) {
5620            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5621            return;
5622        }
5623        int callerUid = Binder.getCallingUid();
5624        // Only the system server can kill an application
5625        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5626            // Post an aysnc message to kill the application
5627            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5628            msg.arg1 = appid;
5629            msg.arg2 = 0;
5630            Bundle bundle = new Bundle();
5631            bundle.putString("pkg", pkg);
5632            bundle.putString("reason", reason);
5633            msg.obj = bundle;
5634            mHandler.sendMessage(msg);
5635        } else {
5636            throw new SecurityException(callerUid + " cannot kill pkg: " +
5637                    pkg);
5638        }
5639    }
5640
5641    @Override
5642    public void closeSystemDialogs(String reason) {
5643        enforceNotIsolatedCaller("closeSystemDialogs");
5644
5645        final int pid = Binder.getCallingPid();
5646        final int uid = Binder.getCallingUid();
5647        final long origId = Binder.clearCallingIdentity();
5648        try {
5649            synchronized (this) {
5650                // Only allow this from foreground processes, so that background
5651                // applications can't abuse it to prevent system UI from being shown.
5652                if (uid >= Process.FIRST_APPLICATION_UID) {
5653                    ProcessRecord proc;
5654                    synchronized (mPidsSelfLocked) {
5655                        proc = mPidsSelfLocked.get(pid);
5656                    }
5657                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5658                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5659                                + " from background process " + proc);
5660                        return;
5661                    }
5662                }
5663                closeSystemDialogsLocked(reason);
5664            }
5665        } finally {
5666            Binder.restoreCallingIdentity(origId);
5667        }
5668    }
5669
5670    void closeSystemDialogsLocked(String reason) {
5671        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5672        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5673                | Intent.FLAG_RECEIVER_FOREGROUND);
5674        if (reason != null) {
5675            intent.putExtra("reason", reason);
5676        }
5677        mWindowManager.closeSystemDialogs(reason);
5678
5679        mStackSupervisor.closeSystemDialogsLocked();
5680
5681        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5682                AppOpsManager.OP_NONE, null, false, false,
5683                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5684    }
5685
5686    @Override
5687    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5688        enforceNotIsolatedCaller("getProcessMemoryInfo");
5689        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5690        for (int i=pids.length-1; i>=0; i--) {
5691            ProcessRecord proc;
5692            int oomAdj;
5693            synchronized (this) {
5694                synchronized (mPidsSelfLocked) {
5695                    proc = mPidsSelfLocked.get(pids[i]);
5696                    oomAdj = proc != null ? proc.setAdj : 0;
5697                }
5698            }
5699            infos[i] = new Debug.MemoryInfo();
5700            Debug.getMemoryInfo(pids[i], infos[i]);
5701            if (proc != null) {
5702                synchronized (this) {
5703                    if (proc.thread != null && proc.setAdj == oomAdj) {
5704                        // Record this for posterity if the process has been stable.
5705                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5706                                infos[i].getTotalUss(), false, proc.pkgList);
5707                    }
5708                }
5709            }
5710        }
5711        return infos;
5712    }
5713
5714    @Override
5715    public long[] getProcessPss(int[] pids) {
5716        enforceNotIsolatedCaller("getProcessPss");
5717        long[] pss = new long[pids.length];
5718        for (int i=pids.length-1; i>=0; i--) {
5719            ProcessRecord proc;
5720            int oomAdj;
5721            synchronized (this) {
5722                synchronized (mPidsSelfLocked) {
5723                    proc = mPidsSelfLocked.get(pids[i]);
5724                    oomAdj = proc != null ? proc.setAdj : 0;
5725                }
5726            }
5727            long[] tmpUss = new long[1];
5728            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5729            if (proc != null) {
5730                synchronized (this) {
5731                    if (proc.thread != null && proc.setAdj == oomAdj) {
5732                        // Record this for posterity if the process has been stable.
5733                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5734                    }
5735                }
5736            }
5737        }
5738        return pss;
5739    }
5740
5741    @Override
5742    public void killApplicationProcess(String processName, int uid) {
5743        if (processName == null) {
5744            return;
5745        }
5746
5747        int callerUid = Binder.getCallingUid();
5748        // Only the system server can kill an application
5749        if (callerUid == Process.SYSTEM_UID) {
5750            synchronized (this) {
5751                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5752                if (app != null && app.thread != null) {
5753                    try {
5754                        app.thread.scheduleSuicide();
5755                    } catch (RemoteException e) {
5756                        // If the other end already died, then our work here is done.
5757                    }
5758                } else {
5759                    Slog.w(TAG, "Process/uid not found attempting kill of "
5760                            + processName + " / " + uid);
5761                }
5762            }
5763        } else {
5764            throw new SecurityException(callerUid + " cannot kill app process: " +
5765                    processName);
5766        }
5767    }
5768
5769    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5770        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5771                false, true, false, false, UserHandle.getUserId(uid), reason);
5772        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5773                Uri.fromParts("package", packageName, null));
5774        if (!mProcessesReady) {
5775            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5776                    | Intent.FLAG_RECEIVER_FOREGROUND);
5777        }
5778        intent.putExtra(Intent.EXTRA_UID, uid);
5779        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5780        broadcastIntentLocked(null, null, intent,
5781                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5782                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5783    }
5784
5785
5786    private final boolean killPackageProcessesLocked(String packageName, int appId,
5787            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5788            boolean doit, boolean evenPersistent, String reason) {
5789        ArrayList<ProcessRecord> procs = new ArrayList<>();
5790
5791        // Remove all processes this package may have touched: all with the
5792        // same UID (except for the system or root user), and all whose name
5793        // matches the package name.
5794        final int NP = mProcessNames.getMap().size();
5795        for (int ip=0; ip<NP; ip++) {
5796            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5797            final int NA = apps.size();
5798            for (int ia=0; ia<NA; ia++) {
5799                ProcessRecord app = apps.valueAt(ia);
5800                if (app.persistent && !evenPersistent) {
5801                    // we don't kill persistent processes
5802                    continue;
5803                }
5804                if (app.removed) {
5805                    if (doit) {
5806                        procs.add(app);
5807                    }
5808                    continue;
5809                }
5810
5811                // Skip process if it doesn't meet our oom adj requirement.
5812                if (app.setAdj < minOomAdj) {
5813                    continue;
5814                }
5815
5816                // If no package is specified, we call all processes under the
5817                // give user id.
5818                if (packageName == null) {
5819                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5820                        continue;
5821                    }
5822                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5823                        continue;
5824                    }
5825                // Package has been specified, we want to hit all processes
5826                // that match it.  We need to qualify this by the processes
5827                // that are running under the specified app and user ID.
5828                } else {
5829                    final boolean isDep = app.pkgDeps != null
5830                            && app.pkgDeps.contains(packageName);
5831                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5832                        continue;
5833                    }
5834                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5835                        continue;
5836                    }
5837                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5838                        continue;
5839                    }
5840                }
5841
5842                // Process has passed all conditions, kill it!
5843                if (!doit) {
5844                    return true;
5845                }
5846                app.removed = true;
5847                procs.add(app);
5848            }
5849        }
5850
5851        int N = procs.size();
5852        for (int i=0; i<N; i++) {
5853            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5854        }
5855        updateOomAdjLocked();
5856        return N > 0;
5857    }
5858
5859    private void cleanupDisabledPackageComponentsLocked(
5860            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5861
5862        Set<String> disabledClasses = null;
5863        boolean packageDisabled = false;
5864        IPackageManager pm = AppGlobals.getPackageManager();
5865
5866        if (changedClasses == null) {
5867            // Nothing changed...
5868            return;
5869        }
5870
5871        // Determine enable/disable state of the package and its components.
5872        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5873        for (int i = changedClasses.length - 1; i >= 0; i--) {
5874            final String changedClass = changedClasses[i];
5875
5876            if (changedClass.equals(packageName)) {
5877                try {
5878                    // Entire package setting changed
5879                    enabled = pm.getApplicationEnabledSetting(packageName,
5880                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5881                } catch (Exception e) {
5882                    // No such package/component; probably racing with uninstall.  In any
5883                    // event it means we have nothing further to do here.
5884                    return;
5885                }
5886                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5887                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5888                if (packageDisabled) {
5889                    // Entire package is disabled.
5890                    // No need to continue to check component states.
5891                    disabledClasses = null;
5892                    break;
5893                }
5894            } else {
5895                try {
5896                    enabled = pm.getComponentEnabledSetting(
5897                            new ComponentName(packageName, changedClass),
5898                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5899                } catch (Exception e) {
5900                    // As above, probably racing with uninstall.
5901                    return;
5902                }
5903                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5904                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5905                    if (disabledClasses == null) {
5906                        disabledClasses = new ArraySet<>(changedClasses.length);
5907                    }
5908                    disabledClasses.add(changedClass);
5909                }
5910            }
5911        }
5912
5913        if (!packageDisabled && disabledClasses == null) {
5914            // Nothing to do here...
5915            return;
5916        }
5917
5918        // Clean-up disabled activities.
5919        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5920                packageName, disabledClasses, true, false, userId) && mBooted) {
5921            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5922            mStackSupervisor.scheduleIdleLocked();
5923        }
5924
5925        // Clean-up disabled tasks
5926        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5927
5928        // Clean-up disabled services.
5929        mServices.bringDownDisabledPackageServicesLocked(
5930                packageName, disabledClasses, userId, false, killProcess, true);
5931
5932        // Clean-up disabled providers.
5933        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5934        mProviderMap.collectPackageProvidersLocked(
5935                packageName, disabledClasses, true, false, userId, providers);
5936        for (int i = providers.size() - 1; i >= 0; i--) {
5937            removeDyingProviderLocked(null, providers.get(i), true);
5938        }
5939
5940        // Clean-up disabled broadcast receivers.
5941        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5942            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5943                    packageName, disabledClasses, userId, true);
5944        }
5945
5946    }
5947
5948    final boolean forceStopPackageLocked(String packageName, int appId,
5949            boolean callerWillRestart, boolean purgeCache, boolean doit,
5950            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5951        int i;
5952
5953        if (userId == UserHandle.USER_ALL && packageName == null) {
5954            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5955        }
5956
5957        if (appId < 0 && packageName != null) {
5958            try {
5959                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5960                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5961            } catch (RemoteException e) {
5962            }
5963        }
5964
5965        if (doit) {
5966            if (packageName != null) {
5967                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5968                        + " user=" + userId + ": " + reason);
5969            } else {
5970                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5971            }
5972
5973            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5974        }
5975
5976        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5977                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5978                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5979
5980        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5981                packageName, null, doit, evenPersistent, userId)) {
5982            if (!doit) {
5983                return true;
5984            }
5985            didSomething = true;
5986        }
5987
5988        if (mServices.bringDownDisabledPackageServicesLocked(
5989                packageName, null, userId, evenPersistent, true, doit)) {
5990            if (!doit) {
5991                return true;
5992            }
5993            didSomething = true;
5994        }
5995
5996        if (packageName == null) {
5997            // Remove all sticky broadcasts from this user.
5998            mStickyBroadcasts.remove(userId);
5999        }
6000
6001        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6002        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6003                userId, providers)) {
6004            if (!doit) {
6005                return true;
6006            }
6007            didSomething = true;
6008        }
6009        for (i = providers.size() - 1; i >= 0; i--) {
6010            removeDyingProviderLocked(null, providers.get(i), true);
6011        }
6012
6013        // Remove transient permissions granted from/to this package/user
6014        removeUriPermissionsForPackageLocked(packageName, userId, false);
6015
6016        if (doit) {
6017            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6018                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6019                        packageName, null, userId, doit);
6020            }
6021        }
6022
6023        if (packageName == null || uninstalling) {
6024            // Remove pending intents.  For now we only do this when force
6025            // stopping users, because we have some problems when doing this
6026            // for packages -- app widgets are not currently cleaned up for
6027            // such packages, so they can be left with bad pending intents.
6028            if (mIntentSenderRecords.size() > 0) {
6029                Iterator<WeakReference<PendingIntentRecord>> it
6030                        = mIntentSenderRecords.values().iterator();
6031                while (it.hasNext()) {
6032                    WeakReference<PendingIntentRecord> wpir = it.next();
6033                    if (wpir == null) {
6034                        it.remove();
6035                        continue;
6036                    }
6037                    PendingIntentRecord pir = wpir.get();
6038                    if (pir == null) {
6039                        it.remove();
6040                        continue;
6041                    }
6042                    if (packageName == null) {
6043                        // Stopping user, remove all objects for the user.
6044                        if (pir.key.userId != userId) {
6045                            // Not the same user, skip it.
6046                            continue;
6047                        }
6048                    } else {
6049                        if (UserHandle.getAppId(pir.uid) != appId) {
6050                            // Different app id, skip it.
6051                            continue;
6052                        }
6053                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6054                            // Different user, skip it.
6055                            continue;
6056                        }
6057                        if (!pir.key.packageName.equals(packageName)) {
6058                            // Different package, skip it.
6059                            continue;
6060                        }
6061                    }
6062                    if (!doit) {
6063                        return true;
6064                    }
6065                    didSomething = true;
6066                    it.remove();
6067                    pir.canceled = true;
6068                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6069                        pir.key.activity.pendingResults.remove(pir.ref);
6070                    }
6071                }
6072            }
6073        }
6074
6075        if (doit) {
6076            if (purgeCache && packageName != null) {
6077                AttributeCache ac = AttributeCache.instance();
6078                if (ac != null) {
6079                    ac.removePackage(packageName);
6080                }
6081            }
6082            if (mBooted) {
6083                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6084                mStackSupervisor.scheduleIdleLocked();
6085            }
6086        }
6087
6088        return didSomething;
6089    }
6090
6091    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6092        ProcessRecord old = mProcessNames.remove(name, uid);
6093        if (old != null) {
6094            old.uidRecord.numProcs--;
6095            if (old.uidRecord.numProcs == 0) {
6096                // No more processes using this uid, tell clients it is gone.
6097                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6098                        "No more processes in " + old.uidRecord);
6099                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6100                mActiveUids.remove(uid);
6101                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6102            }
6103            old.uidRecord = null;
6104        }
6105        mIsolatedProcesses.remove(uid);
6106        return old;
6107    }
6108
6109    private final void addProcessNameLocked(ProcessRecord proc) {
6110        // We shouldn't already have a process under this name, but just in case we
6111        // need to clean up whatever may be there now.
6112        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6113        if (old == proc && proc.persistent) {
6114            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6115            Slog.w(TAG, "Re-adding persistent process " + proc);
6116        } else if (old != null) {
6117            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6118        }
6119        UidRecord uidRec = mActiveUids.get(proc.uid);
6120        if (uidRec == null) {
6121            uidRec = new UidRecord(proc.uid);
6122            // This is the first appearance of the uid, report it now!
6123            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6124                    "Creating new process uid: " + uidRec);
6125            mActiveUids.put(proc.uid, uidRec);
6126            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6127            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6128        }
6129        proc.uidRecord = uidRec;
6130        uidRec.numProcs++;
6131        mProcessNames.put(proc.processName, proc.uid, proc);
6132        if (proc.isolated) {
6133            mIsolatedProcesses.put(proc.uid, proc);
6134        }
6135    }
6136
6137    boolean removeProcessLocked(ProcessRecord app,
6138            boolean callerWillRestart, boolean allowRestart, String reason) {
6139        final String name = app.processName;
6140        final int uid = app.uid;
6141        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6142            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6143
6144        removeProcessNameLocked(name, uid);
6145        if (mHeavyWeightProcess == app) {
6146            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6147                    mHeavyWeightProcess.userId, 0));
6148            mHeavyWeightProcess = null;
6149        }
6150        boolean needRestart = false;
6151        if (app.pid > 0 && app.pid != MY_PID) {
6152            int pid = app.pid;
6153            synchronized (mPidsSelfLocked) {
6154                mPidsSelfLocked.remove(pid);
6155                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6156            }
6157            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6158            if (app.isolated) {
6159                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6160            }
6161            boolean willRestart = false;
6162            if (app.persistent && !app.isolated) {
6163                if (!callerWillRestart) {
6164                    willRestart = true;
6165                } else {
6166                    needRestart = true;
6167                }
6168            }
6169            app.kill(reason, true);
6170            handleAppDiedLocked(app, willRestart, allowRestart);
6171            if (willRestart) {
6172                removeLruProcessLocked(app);
6173                addAppLocked(app.info, false, null /* ABI override */);
6174            }
6175        } else {
6176            mRemovedProcesses.add(app);
6177        }
6178
6179        return needRestart;
6180    }
6181
6182    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6183        cleanupAppInLaunchingProvidersLocked(app, true);
6184        removeProcessLocked(app, false, true, "timeout publishing content providers");
6185    }
6186
6187    private final void processStartTimedOutLocked(ProcessRecord app) {
6188        final int pid = app.pid;
6189        boolean gone = false;
6190        synchronized (mPidsSelfLocked) {
6191            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6192            if (knownApp != null && knownApp.thread == null) {
6193                mPidsSelfLocked.remove(pid);
6194                gone = true;
6195            }
6196        }
6197
6198        if (gone) {
6199            Slog.w(TAG, "Process " + app + " failed to attach");
6200            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6201                    pid, app.uid, app.processName);
6202            removeProcessNameLocked(app.processName, app.uid);
6203            if (mHeavyWeightProcess == app) {
6204                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6205                        mHeavyWeightProcess.userId, 0));
6206                mHeavyWeightProcess = null;
6207            }
6208            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6209            if (app.isolated) {
6210                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6211            }
6212            // Take care of any launching providers waiting for this process.
6213            cleanupAppInLaunchingProvidersLocked(app, true);
6214            // Take care of any services that are waiting for the process.
6215            mServices.processStartTimedOutLocked(app);
6216            app.kill("start timeout", true);
6217            removeLruProcessLocked(app);
6218            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6219                Slog.w(TAG, "Unattached app died before backup, skipping");
6220                try {
6221                    IBackupManager bm = IBackupManager.Stub.asInterface(
6222                            ServiceManager.getService(Context.BACKUP_SERVICE));
6223                    bm.agentDisconnected(app.info.packageName);
6224                } catch (RemoteException e) {
6225                    // Can't happen; the backup manager is local
6226                }
6227            }
6228            if (isPendingBroadcastProcessLocked(pid)) {
6229                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6230                skipPendingBroadcastLocked(pid);
6231            }
6232        } else {
6233            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6234        }
6235    }
6236
6237    private final boolean attachApplicationLocked(IApplicationThread thread,
6238            int pid) {
6239
6240        // Find the application record that is being attached...  either via
6241        // the pid if we are running in multiple processes, or just pull the
6242        // next app record if we are emulating process with anonymous threads.
6243        ProcessRecord app;
6244        if (pid != MY_PID && pid >= 0) {
6245            synchronized (mPidsSelfLocked) {
6246                app = mPidsSelfLocked.get(pid);
6247            }
6248        } else {
6249            app = null;
6250        }
6251
6252        if (app == null) {
6253            Slog.w(TAG, "No pending application record for pid " + pid
6254                    + " (IApplicationThread " + thread + "); dropping process");
6255            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6256            if (pid > 0 && pid != MY_PID) {
6257                Process.killProcessQuiet(pid);
6258                //TODO: killProcessGroup(app.info.uid, pid);
6259            } else {
6260                try {
6261                    thread.scheduleExit();
6262                } catch (Exception e) {
6263                    // Ignore exceptions.
6264                }
6265            }
6266            return false;
6267        }
6268
6269        // If this application record is still attached to a previous
6270        // process, clean it up now.
6271        if (app.thread != null) {
6272            handleAppDiedLocked(app, true, true);
6273        }
6274
6275        // Tell the process all about itself.
6276
6277        if (DEBUG_ALL) Slog.v(
6278                TAG, "Binding process pid " + pid + " to record " + app);
6279
6280        final String processName = app.processName;
6281        try {
6282            AppDeathRecipient adr = new AppDeathRecipient(
6283                    app, pid, thread);
6284            thread.asBinder().linkToDeath(adr, 0);
6285            app.deathRecipient = adr;
6286        } catch (RemoteException e) {
6287            app.resetPackageList(mProcessStats);
6288            startProcessLocked(app, "link fail", processName);
6289            return false;
6290        }
6291
6292        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6293
6294        app.makeActive(thread, mProcessStats);
6295        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6296        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6297        app.forcingToForeground = null;
6298        updateProcessForegroundLocked(app, false, false);
6299        app.hasShownUi = false;
6300        app.debugging = false;
6301        app.cached = false;
6302        app.killedByAm = false;
6303        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6304
6305        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6306
6307        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6308        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6309
6310        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6311            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6312            msg.obj = app;
6313            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6314        }
6315
6316        if (!normalMode) {
6317            Slog.i(TAG, "Launching preboot mode app: " + app);
6318        }
6319
6320        if (DEBUG_ALL) Slog.v(
6321            TAG, "New app record " + app
6322            + " thread=" + thread.asBinder() + " pid=" + pid);
6323        try {
6324            int testMode = IApplicationThread.DEBUG_OFF;
6325            if (mDebugApp != null && mDebugApp.equals(processName)) {
6326                testMode = mWaitForDebugger
6327                    ? IApplicationThread.DEBUG_WAIT
6328                    : IApplicationThread.DEBUG_ON;
6329                app.debugging = true;
6330                if (mDebugTransient) {
6331                    mDebugApp = mOrigDebugApp;
6332                    mWaitForDebugger = mOrigWaitForDebugger;
6333                }
6334            }
6335            String profileFile = app.instrumentationProfileFile;
6336            ParcelFileDescriptor profileFd = null;
6337            int samplingInterval = 0;
6338            boolean profileAutoStop = false;
6339            if (mProfileApp != null && mProfileApp.equals(processName)) {
6340                mProfileProc = app;
6341                profileFile = mProfileFile;
6342                profileFd = mProfileFd;
6343                samplingInterval = mSamplingInterval;
6344                profileAutoStop = mAutoStopProfiler;
6345            }
6346            boolean enableTrackAllocation = false;
6347            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6348                enableTrackAllocation = true;
6349                mTrackAllocationApp = null;
6350            }
6351
6352            // If the app is being launched for restore or full backup, set it up specially
6353            boolean isRestrictedBackupMode = false;
6354            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6355                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6356                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6357                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6358                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6359            }
6360
6361            notifyPackageUse(app.instrumentationInfo != null
6362                    ? app.instrumentationInfo.packageName
6363                    : app.info.packageName);
6364            if (app.instrumentationClass != null) {
6365                notifyPackageUse(app.instrumentationClass.getPackageName());
6366            }
6367            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6368                    + processName + " with config " + mConfiguration);
6369            ApplicationInfo appInfo = app.instrumentationInfo != null
6370                    ? app.instrumentationInfo : app.info;
6371            app.compat = compatibilityInfoForPackageLocked(appInfo);
6372            if (profileFd != null) {
6373                profileFd = profileFd.dup();
6374            }
6375            ProfilerInfo profilerInfo = profileFile == null ? null
6376                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6377            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6378                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6379                    app.instrumentationUiAutomationConnection, testMode,
6380                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6381                    isRestrictedBackupMode || !normalMode, app.persistent,
6382                    new Configuration(mConfiguration), app.compat,
6383                    getCommonServicesLocked(app.isolated),
6384                    mCoreSettingsObserver.getCoreSettingsLocked());
6385            updateLruProcessLocked(app, false, null);
6386            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6387        } catch (Exception e) {
6388            // todo: Yikes!  What should we do?  For now we will try to
6389            // start another process, but that could easily get us in
6390            // an infinite loop of restarting processes...
6391            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6392
6393            app.resetPackageList(mProcessStats);
6394            app.unlinkDeathRecipient();
6395            startProcessLocked(app, "bind fail", processName);
6396            return false;
6397        }
6398
6399        // Remove this record from the list of starting applications.
6400        mPersistentStartingProcesses.remove(app);
6401        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6402                "Attach application locked removing on hold: " + app);
6403        mProcessesOnHold.remove(app);
6404
6405        boolean badApp = false;
6406        boolean didSomething = false;
6407
6408        // See if the top visible activity is waiting to run in this process...
6409        if (normalMode) {
6410            try {
6411                if (mStackSupervisor.attachApplicationLocked(app)) {
6412                    didSomething = true;
6413                }
6414            } catch (Exception e) {
6415                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6416                badApp = true;
6417            }
6418        }
6419
6420        // Find any services that should be running in this process...
6421        if (!badApp) {
6422            try {
6423                didSomething |= mServices.attachApplicationLocked(app, processName);
6424            } catch (Exception e) {
6425                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6426                badApp = true;
6427            }
6428        }
6429
6430        // Check if a next-broadcast receiver is in this process...
6431        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6432            try {
6433                didSomething |= sendPendingBroadcastsLocked(app);
6434            } catch (Exception e) {
6435                // If the app died trying to launch the receiver we declare it 'bad'
6436                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6437                badApp = true;
6438            }
6439        }
6440
6441        // Check whether the next backup agent is in this process...
6442        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6443            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6444                    "New app is backup target, launching agent for " + app);
6445            notifyPackageUse(mBackupTarget.appInfo.packageName);
6446            try {
6447                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6448                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6449                        mBackupTarget.backupMode);
6450            } catch (Exception e) {
6451                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6452                badApp = true;
6453            }
6454        }
6455
6456        if (badApp) {
6457            app.kill("error during init", true);
6458            handleAppDiedLocked(app, false, true);
6459            return false;
6460        }
6461
6462        if (!didSomething) {
6463            updateOomAdjLocked();
6464        }
6465
6466        return true;
6467    }
6468
6469    @Override
6470    public final void attachApplication(IApplicationThread thread) {
6471        synchronized (this) {
6472            int callingPid = Binder.getCallingPid();
6473            final long origId = Binder.clearCallingIdentity();
6474            attachApplicationLocked(thread, callingPid);
6475            Binder.restoreCallingIdentity(origId);
6476        }
6477    }
6478
6479    @Override
6480    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6481        final long origId = Binder.clearCallingIdentity();
6482        synchronized (this) {
6483            ActivityStack stack = ActivityRecord.getStackLocked(token);
6484            if (stack != null) {
6485                ActivityRecord r =
6486                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6487                if (stopProfiling) {
6488                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6489                        try {
6490                            mProfileFd.close();
6491                        } catch (IOException e) {
6492                        }
6493                        clearProfilerLocked();
6494                    }
6495                }
6496            }
6497        }
6498        Binder.restoreCallingIdentity(origId);
6499    }
6500
6501    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6502        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6503                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6504    }
6505
6506    void enableScreenAfterBoot() {
6507        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6508                SystemClock.uptimeMillis());
6509        mWindowManager.enableScreenAfterBoot();
6510
6511        synchronized (this) {
6512            updateEventDispatchingLocked();
6513        }
6514    }
6515
6516    @Override
6517    public void showBootMessage(final CharSequence msg, final boolean always) {
6518        if (Binder.getCallingUid() != Process.myUid()) {
6519            // These days only the core system can call this, so apps can't get in
6520            // the way of what we show about running them.
6521        }
6522        mWindowManager.showBootMessage(msg, always);
6523    }
6524
6525    @Override
6526    public void keyguardWaitingForActivityDrawn() {
6527        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6528        final long token = Binder.clearCallingIdentity();
6529        try {
6530            synchronized (this) {
6531                if (DEBUG_LOCKSCREEN) logLockScreen("");
6532                mWindowManager.keyguardWaitingForActivityDrawn();
6533                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6534                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6535                    updateSleepIfNeededLocked();
6536                }
6537            }
6538        } finally {
6539            Binder.restoreCallingIdentity(token);
6540        }
6541    }
6542
6543    @Override
6544    public void keyguardGoingAway(int flags) {
6545        enforceNotIsolatedCaller("keyguardGoingAway");
6546        final long token = Binder.clearCallingIdentity();
6547        try {
6548            synchronized (this) {
6549                if (DEBUG_LOCKSCREEN) logLockScreen("");
6550                mWindowManager.keyguardGoingAway(flags);
6551                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6552                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6553                    updateSleepIfNeededLocked();
6554
6555                    // Some stack visibility might change (e.g. docked stack)
6556                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6557                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6558                }
6559            }
6560        } finally {
6561            Binder.restoreCallingIdentity(token);
6562        }
6563    }
6564
6565    final void finishBooting() {
6566        synchronized (this) {
6567            if (!mBootAnimationComplete) {
6568                mCallFinishBooting = true;
6569                return;
6570            }
6571            mCallFinishBooting = false;
6572        }
6573
6574        ArraySet<String> completedIsas = new ArraySet<String>();
6575        for (String abi : Build.SUPPORTED_ABIS) {
6576            Process.establishZygoteConnectionForAbi(abi);
6577            final String instructionSet = VMRuntime.getInstructionSet(abi);
6578            if (!completedIsas.contains(instructionSet)) {
6579                try {
6580                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6581                } catch (InstallerException e) {
6582                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6583                }
6584                completedIsas.add(instructionSet);
6585            }
6586        }
6587
6588        IntentFilter pkgFilter = new IntentFilter();
6589        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6590        pkgFilter.addDataScheme("package");
6591        mContext.registerReceiver(new BroadcastReceiver() {
6592            @Override
6593            public void onReceive(Context context, Intent intent) {
6594                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6595                if (pkgs != null) {
6596                    for (String pkg : pkgs) {
6597                        synchronized (ActivityManagerService.this) {
6598                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6599                                    0, "query restart")) {
6600                                setResultCode(Activity.RESULT_OK);
6601                                return;
6602                            }
6603                        }
6604                    }
6605                }
6606            }
6607        }, pkgFilter);
6608
6609        IntentFilter dumpheapFilter = new IntentFilter();
6610        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6611        mContext.registerReceiver(new BroadcastReceiver() {
6612            @Override
6613            public void onReceive(Context context, Intent intent) {
6614                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6615                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6616                } else {
6617                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6618                }
6619            }
6620        }, dumpheapFilter);
6621
6622        // Let system services know.
6623        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6624
6625        synchronized (this) {
6626            // Ensure that any processes we had put on hold are now started
6627            // up.
6628            final int NP = mProcessesOnHold.size();
6629            if (NP > 0) {
6630                ArrayList<ProcessRecord> procs =
6631                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6632                for (int ip=0; ip<NP; ip++) {
6633                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6634                            + procs.get(ip));
6635                    startProcessLocked(procs.get(ip), "on-hold", null);
6636                }
6637            }
6638
6639            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6640                // Start looking for apps that are abusing wake locks.
6641                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6642                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6643                // Tell anyone interested that we are done booting!
6644                SystemProperties.set("sys.boot_completed", "1");
6645
6646                // And trigger dev.bootcomplete if we are not showing encryption progress
6647                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6648                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6649                    SystemProperties.set("dev.bootcomplete", "1");
6650                }
6651                mUserController.sendBootCompletedLocked(
6652                        new IIntentReceiver.Stub() {
6653                            @Override
6654                            public void performReceive(Intent intent, int resultCode,
6655                                    String data, Bundle extras, boolean ordered,
6656                                    boolean sticky, int sendingUser) {
6657                                synchronized (ActivityManagerService.this) {
6658                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6659                                            true, false);
6660                                }
6661                            }
6662                        });
6663                scheduleStartProfilesLocked();
6664            }
6665        }
6666    }
6667
6668    @Override
6669    public void bootAnimationComplete() {
6670        final boolean callFinishBooting;
6671        synchronized (this) {
6672            callFinishBooting = mCallFinishBooting;
6673            mBootAnimationComplete = true;
6674        }
6675        if (callFinishBooting) {
6676            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6677            finishBooting();
6678            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6679        }
6680    }
6681
6682    final void ensureBootCompleted() {
6683        boolean booting;
6684        boolean enableScreen;
6685        synchronized (this) {
6686            booting = mBooting;
6687            mBooting = false;
6688            enableScreen = !mBooted;
6689            mBooted = true;
6690        }
6691
6692        if (booting) {
6693            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6694            finishBooting();
6695            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6696        }
6697
6698        if (enableScreen) {
6699            enableScreenAfterBoot();
6700        }
6701    }
6702
6703    @Override
6704    public final void activityResumed(IBinder token) {
6705        final long origId = Binder.clearCallingIdentity();
6706        synchronized(this) {
6707            ActivityStack stack = ActivityRecord.getStackLocked(token);
6708            if (stack != null) {
6709                stack.activityResumedLocked(token);
6710            }
6711        }
6712        Binder.restoreCallingIdentity(origId);
6713    }
6714
6715    @Override
6716    public final void activityPaused(IBinder token) {
6717        final long origId = Binder.clearCallingIdentity();
6718        synchronized(this) {
6719            ActivityStack stack = ActivityRecord.getStackLocked(token);
6720            if (stack != null) {
6721                stack.activityPausedLocked(token, false);
6722            }
6723        }
6724        Binder.restoreCallingIdentity(origId);
6725    }
6726
6727    @Override
6728    public final void activityStopped(IBinder token, Bundle icicle,
6729            PersistableBundle persistentState, CharSequence description) {
6730        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6731
6732        // Refuse possible leaked file descriptors
6733        if (icicle != null && icicle.hasFileDescriptors()) {
6734            throw new IllegalArgumentException("File descriptors passed in Bundle");
6735        }
6736
6737        final long origId = Binder.clearCallingIdentity();
6738
6739        synchronized (this) {
6740            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6741            if (r != null) {
6742                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6743            }
6744        }
6745
6746        trimApplications();
6747
6748        Binder.restoreCallingIdentity(origId);
6749    }
6750
6751    @Override
6752    public final void activityDestroyed(IBinder token) {
6753        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6754        synchronized (this) {
6755            ActivityStack stack = ActivityRecord.getStackLocked(token);
6756            if (stack != null) {
6757                stack.activityDestroyedLocked(token, "activityDestroyed");
6758            }
6759        }
6760    }
6761
6762    @Override
6763    public final void activityRelaunched(IBinder token) {
6764        final long origId = Binder.clearCallingIdentity();
6765        synchronized (this) {
6766            mStackSupervisor.activityRelaunchedLocked(token);
6767        }
6768        Binder.restoreCallingIdentity(origId);
6769    }
6770
6771    @Override
6772    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6773            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6774        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6775                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6776        synchronized (this) {
6777            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6778            if (record == null) {
6779                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6780                        + "found for: " + token);
6781            }
6782            record.setSizeConfigurations(horizontalSizeConfiguration,
6783                    verticalSizeConfigurations, smallestSizeConfigurations);
6784        }
6785    }
6786
6787    @Override
6788    public final void backgroundResourcesReleased(IBinder token) {
6789        final long origId = Binder.clearCallingIdentity();
6790        try {
6791            synchronized (this) {
6792                ActivityStack stack = ActivityRecord.getStackLocked(token);
6793                if (stack != null) {
6794                    stack.backgroundResourcesReleased();
6795                }
6796            }
6797        } finally {
6798            Binder.restoreCallingIdentity(origId);
6799        }
6800    }
6801
6802    @Override
6803    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6804        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6805    }
6806
6807    @Override
6808    public final void notifyEnterAnimationComplete(IBinder token) {
6809        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6810    }
6811
6812    @Override
6813    public String getCallingPackage(IBinder token) {
6814        synchronized (this) {
6815            ActivityRecord r = getCallingRecordLocked(token);
6816            return r != null ? r.info.packageName : null;
6817        }
6818    }
6819
6820    @Override
6821    public ComponentName getCallingActivity(IBinder token) {
6822        synchronized (this) {
6823            ActivityRecord r = getCallingRecordLocked(token);
6824            return r != null ? r.intent.getComponent() : null;
6825        }
6826    }
6827
6828    private ActivityRecord getCallingRecordLocked(IBinder token) {
6829        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6830        if (r == null) {
6831            return null;
6832        }
6833        return r.resultTo;
6834    }
6835
6836    @Override
6837    public ComponentName getActivityClassForToken(IBinder token) {
6838        synchronized(this) {
6839            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6840            if (r == null) {
6841                return null;
6842            }
6843            return r.intent.getComponent();
6844        }
6845    }
6846
6847    @Override
6848    public String getPackageForToken(IBinder token) {
6849        synchronized(this) {
6850            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6851            if (r == null) {
6852                return null;
6853            }
6854            return r.packageName;
6855        }
6856    }
6857
6858    @Override
6859    public boolean isRootVoiceInteraction(IBinder token) {
6860        synchronized(this) {
6861            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6862            if (r == null) {
6863                return false;
6864            }
6865            return r.rootVoiceInteraction;
6866        }
6867    }
6868
6869    @Override
6870    public IIntentSender getIntentSender(int type,
6871            String packageName, IBinder token, String resultWho,
6872            int requestCode, Intent[] intents, String[] resolvedTypes,
6873            int flags, Bundle bOptions, int userId) {
6874        enforceNotIsolatedCaller("getIntentSender");
6875        // Refuse possible leaked file descriptors
6876        if (intents != null) {
6877            if (intents.length < 1) {
6878                throw new IllegalArgumentException("Intents array length must be >= 1");
6879            }
6880            for (int i=0; i<intents.length; i++) {
6881                Intent intent = intents[i];
6882                if (intent != null) {
6883                    if (intent.hasFileDescriptors()) {
6884                        throw new IllegalArgumentException("File descriptors passed in Intent");
6885                    }
6886                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6887                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6888                        throw new IllegalArgumentException(
6889                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6890                    }
6891                    intents[i] = new Intent(intent);
6892                }
6893            }
6894            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6895                throw new IllegalArgumentException(
6896                        "Intent array length does not match resolvedTypes length");
6897            }
6898        }
6899        if (bOptions != null) {
6900            if (bOptions.hasFileDescriptors()) {
6901                throw new IllegalArgumentException("File descriptors passed in options");
6902            }
6903        }
6904
6905        synchronized(this) {
6906            int callingUid = Binder.getCallingUid();
6907            int origUserId = userId;
6908            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6909                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6910                    ALLOW_NON_FULL, "getIntentSender", null);
6911            if (origUserId == UserHandle.USER_CURRENT) {
6912                // We don't want to evaluate this until the pending intent is
6913                // actually executed.  However, we do want to always do the
6914                // security checking for it above.
6915                userId = UserHandle.USER_CURRENT;
6916            }
6917            try {
6918                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6919                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6920                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6921                    if (!UserHandle.isSameApp(callingUid, uid)) {
6922                        String msg = "Permission Denial: getIntentSender() from pid="
6923                            + Binder.getCallingPid()
6924                            + ", uid=" + Binder.getCallingUid()
6925                            + ", (need uid=" + uid + ")"
6926                            + " is not allowed to send as package " + packageName;
6927                        Slog.w(TAG, msg);
6928                        throw new SecurityException(msg);
6929                    }
6930                }
6931
6932                return getIntentSenderLocked(type, packageName, callingUid, userId,
6933                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6934
6935            } catch (RemoteException e) {
6936                throw new SecurityException(e);
6937            }
6938        }
6939    }
6940
6941    IIntentSender getIntentSenderLocked(int type, String packageName,
6942            int callingUid, int userId, IBinder token, String resultWho,
6943            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6944            Bundle bOptions) {
6945        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6946        ActivityRecord activity = null;
6947        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6948            activity = ActivityRecord.isInStackLocked(token);
6949            if (activity == null) {
6950                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6951                return null;
6952            }
6953            if (activity.finishing) {
6954                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6955                return null;
6956            }
6957        }
6958
6959        // We're going to be splicing together extras before sending, so we're
6960        // okay poking into any contained extras.
6961        if (intents != null) {
6962            for (int i = 0; i < intents.length; i++) {
6963                intents[i].setDefusable(true);
6964            }
6965        }
6966        Bundle.setDefusable(bOptions, true);
6967
6968        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6969        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6970        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6971        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6972                |PendingIntent.FLAG_UPDATE_CURRENT);
6973
6974        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6975                type, packageName, activity, resultWho,
6976                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6977        WeakReference<PendingIntentRecord> ref;
6978        ref = mIntentSenderRecords.get(key);
6979        PendingIntentRecord rec = ref != null ? ref.get() : null;
6980        if (rec != null) {
6981            if (!cancelCurrent) {
6982                if (updateCurrent) {
6983                    if (rec.key.requestIntent != null) {
6984                        rec.key.requestIntent.replaceExtras(intents != null ?
6985                                intents[intents.length - 1] : null);
6986                    }
6987                    if (intents != null) {
6988                        intents[intents.length-1] = rec.key.requestIntent;
6989                        rec.key.allIntents = intents;
6990                        rec.key.allResolvedTypes = resolvedTypes;
6991                    } else {
6992                        rec.key.allIntents = null;
6993                        rec.key.allResolvedTypes = null;
6994                    }
6995                }
6996                return rec;
6997            }
6998            rec.canceled = true;
6999            mIntentSenderRecords.remove(key);
7000        }
7001        if (noCreate) {
7002            return rec;
7003        }
7004        rec = new PendingIntentRecord(this, key, callingUid);
7005        mIntentSenderRecords.put(key, rec.ref);
7006        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7007            if (activity.pendingResults == null) {
7008                activity.pendingResults
7009                        = new HashSet<WeakReference<PendingIntentRecord>>();
7010            }
7011            activity.pendingResults.add(rec.ref);
7012        }
7013        return rec;
7014    }
7015
7016    @Override
7017    public void cancelIntentSender(IIntentSender sender) {
7018        if (!(sender instanceof PendingIntentRecord)) {
7019            return;
7020        }
7021        synchronized(this) {
7022            PendingIntentRecord rec = (PendingIntentRecord)sender;
7023            try {
7024                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7025                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7026                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7027                    String msg = "Permission Denial: cancelIntentSender() from pid="
7028                        + Binder.getCallingPid()
7029                        + ", uid=" + Binder.getCallingUid()
7030                        + " is not allowed to cancel packges "
7031                        + rec.key.packageName;
7032                    Slog.w(TAG, msg);
7033                    throw new SecurityException(msg);
7034                }
7035            } catch (RemoteException e) {
7036                throw new SecurityException(e);
7037            }
7038            cancelIntentSenderLocked(rec, true);
7039        }
7040    }
7041
7042    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7043        rec.canceled = true;
7044        mIntentSenderRecords.remove(rec.key);
7045        if (cleanActivity && rec.key.activity != null) {
7046            rec.key.activity.pendingResults.remove(rec.ref);
7047        }
7048    }
7049
7050    @Override
7051    public String getPackageForIntentSender(IIntentSender pendingResult) {
7052        if (!(pendingResult instanceof PendingIntentRecord)) {
7053            return null;
7054        }
7055        try {
7056            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7057            return res.key.packageName;
7058        } catch (ClassCastException e) {
7059        }
7060        return null;
7061    }
7062
7063    @Override
7064    public int getUidForIntentSender(IIntentSender sender) {
7065        if (sender instanceof PendingIntentRecord) {
7066            try {
7067                PendingIntentRecord res = (PendingIntentRecord)sender;
7068                return res.uid;
7069            } catch (ClassCastException e) {
7070            }
7071        }
7072        return -1;
7073    }
7074
7075    @Override
7076    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7077        if (!(pendingResult instanceof PendingIntentRecord)) {
7078            return false;
7079        }
7080        try {
7081            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7082            if (res.key.allIntents == null) {
7083                return false;
7084            }
7085            for (int i=0; i<res.key.allIntents.length; i++) {
7086                Intent intent = res.key.allIntents[i];
7087                if (intent.getPackage() != null && intent.getComponent() != null) {
7088                    return false;
7089                }
7090            }
7091            return true;
7092        } catch (ClassCastException e) {
7093        }
7094        return false;
7095    }
7096
7097    @Override
7098    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7099        if (!(pendingResult instanceof PendingIntentRecord)) {
7100            return false;
7101        }
7102        try {
7103            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7104            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7105                return true;
7106            }
7107            return false;
7108        } catch (ClassCastException e) {
7109        }
7110        return false;
7111    }
7112
7113    @Override
7114    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7115        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7116                "getIntentForIntentSender()");
7117        if (!(pendingResult instanceof PendingIntentRecord)) {
7118            return null;
7119        }
7120        try {
7121            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7122            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7123        } catch (ClassCastException e) {
7124        }
7125        return null;
7126    }
7127
7128    @Override
7129    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7130        if (!(pendingResult instanceof PendingIntentRecord)) {
7131            return null;
7132        }
7133        try {
7134            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7135            synchronized (this) {
7136                return getTagForIntentSenderLocked(res, prefix);
7137            }
7138        } catch (ClassCastException e) {
7139        }
7140        return null;
7141    }
7142
7143    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7144        final Intent intent = res.key.requestIntent;
7145        if (intent != null) {
7146            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7147                    || res.lastTagPrefix.equals(prefix))) {
7148                return res.lastTag;
7149            }
7150            res.lastTagPrefix = prefix;
7151            final StringBuilder sb = new StringBuilder(128);
7152            if (prefix != null) {
7153                sb.append(prefix);
7154            }
7155            if (intent.getAction() != null) {
7156                sb.append(intent.getAction());
7157            } else if (intent.getComponent() != null) {
7158                intent.getComponent().appendShortString(sb);
7159            } else {
7160                sb.append("?");
7161            }
7162            return res.lastTag = sb.toString();
7163        }
7164        return null;
7165    }
7166
7167    @Override
7168    public void setProcessLimit(int max) {
7169        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7170                "setProcessLimit()");
7171        synchronized (this) {
7172            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7173            mProcessLimitOverride = max;
7174        }
7175        trimApplications();
7176    }
7177
7178    @Override
7179    public int getProcessLimit() {
7180        synchronized (this) {
7181            return mProcessLimitOverride;
7182        }
7183    }
7184
7185    void foregroundTokenDied(ForegroundToken token) {
7186        synchronized (ActivityManagerService.this) {
7187            synchronized (mPidsSelfLocked) {
7188                ForegroundToken cur
7189                    = mForegroundProcesses.get(token.pid);
7190                if (cur != token) {
7191                    return;
7192                }
7193                mForegroundProcesses.remove(token.pid);
7194                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7195                if (pr == null) {
7196                    return;
7197                }
7198                pr.forcingToForeground = null;
7199                updateProcessForegroundLocked(pr, false, false);
7200            }
7201            updateOomAdjLocked();
7202        }
7203    }
7204
7205    @Override
7206    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7207        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7208                "setProcessForeground()");
7209        synchronized(this) {
7210            boolean changed = false;
7211
7212            synchronized (mPidsSelfLocked) {
7213                ProcessRecord pr = mPidsSelfLocked.get(pid);
7214                if (pr == null && isForeground) {
7215                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7216                    return;
7217                }
7218                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7219                if (oldToken != null) {
7220                    oldToken.token.unlinkToDeath(oldToken, 0);
7221                    mForegroundProcesses.remove(pid);
7222                    if (pr != null) {
7223                        pr.forcingToForeground = null;
7224                    }
7225                    changed = true;
7226                }
7227                if (isForeground && token != null) {
7228                    ForegroundToken newToken = new ForegroundToken() {
7229                        @Override
7230                        public void binderDied() {
7231                            foregroundTokenDied(this);
7232                        }
7233                    };
7234                    newToken.pid = pid;
7235                    newToken.token = token;
7236                    try {
7237                        token.linkToDeath(newToken, 0);
7238                        mForegroundProcesses.put(pid, newToken);
7239                        pr.forcingToForeground = token;
7240                        changed = true;
7241                    } catch (RemoteException e) {
7242                        // If the process died while doing this, we will later
7243                        // do the cleanup with the process death link.
7244                    }
7245                }
7246            }
7247
7248            if (changed) {
7249                updateOomAdjLocked();
7250            }
7251        }
7252    }
7253
7254    @Override
7255    public boolean isAppForeground(int uid) throws RemoteException {
7256        synchronized (this) {
7257            UidRecord uidRec = mActiveUids.get(uid);
7258            if (uidRec == null || uidRec.idle) {
7259                return false;
7260            }
7261            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7262        }
7263    }
7264
7265    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7266    // be guarded by permission checking.
7267    int getUidState(int uid) {
7268        synchronized (this) {
7269            UidRecord uidRec = mActiveUids.get(uid);
7270            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7271        }
7272    }
7273
7274    @Override
7275    public boolean isInMultiWindowMode(IBinder token) {
7276        final long origId = Binder.clearCallingIdentity();
7277        try {
7278            synchronized(this) {
7279                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7280                if (r == null) {
7281                    return false;
7282                }
7283                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7284                return !r.task.mFullscreen;
7285            }
7286        } finally {
7287            Binder.restoreCallingIdentity(origId);
7288        }
7289    }
7290
7291    @Override
7292    public boolean isInPictureInPictureMode(IBinder token) {
7293        final long origId = Binder.clearCallingIdentity();
7294        try {
7295            synchronized(this) {
7296                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7297                if (stack == null) {
7298                    return false;
7299                }
7300                return stack.mStackId == PINNED_STACK_ID;
7301            }
7302        } finally {
7303            Binder.restoreCallingIdentity(origId);
7304        }
7305    }
7306
7307    @Override
7308    public void enterPictureInPictureMode(IBinder token) {
7309        final long origId = Binder.clearCallingIdentity();
7310        try {
7311            synchronized(this) {
7312                if (!mSupportsPictureInPicture) {
7313                    throw new IllegalStateException("enterPictureInPictureMode: "
7314                            + "Device doesn't support picture-in-picture mode.");
7315                }
7316
7317                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7318
7319                if (r == null) {
7320                    throw new IllegalStateException("enterPictureInPictureMode: "
7321                            + "Can't find activity for token=" + token);
7322                }
7323
7324                if (!r.supportsPictureInPicture()) {
7325                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7326                            + "Picture-In-Picture not supported for r=" + r);
7327                }
7328
7329                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7330                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7331                        ? mDefaultPinnedStackBounds : null;
7332
7333                mStackSupervisor.moveActivityToPinnedStackLocked(
7334                        r, "enterPictureInPictureMode", bounds);
7335            }
7336        } finally {
7337            Binder.restoreCallingIdentity(origId);
7338        }
7339    }
7340
7341    // =========================================================
7342    // PROCESS INFO
7343    // =========================================================
7344
7345    static class ProcessInfoService extends IProcessInfoService.Stub {
7346        final ActivityManagerService mActivityManagerService;
7347        ProcessInfoService(ActivityManagerService activityManagerService) {
7348            mActivityManagerService = activityManagerService;
7349        }
7350
7351        @Override
7352        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7353            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7354                    /*in*/ pids, /*out*/ states, null);
7355        }
7356
7357        @Override
7358        public void getProcessStatesAndOomScoresFromPids(
7359                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7360            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7361                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7362        }
7363    }
7364
7365    /**
7366     * For each PID in the given input array, write the current process state
7367     * for that process into the states array, or -1 to indicate that no
7368     * process with the given PID exists. If scores array is provided, write
7369     * the oom score for the process into the scores array, with INVALID_ADJ
7370     * indicating the PID doesn't exist.
7371     */
7372    public void getProcessStatesAndOomScoresForPIDs(
7373            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7374        if (scores != null) {
7375            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7376                    "getProcessStatesAndOomScoresForPIDs()");
7377        }
7378
7379        if (pids == null) {
7380            throw new NullPointerException("pids");
7381        } else if (states == null) {
7382            throw new NullPointerException("states");
7383        } else if (pids.length != states.length) {
7384            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7385        } else if (scores != null && pids.length != scores.length) {
7386            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7387        }
7388
7389        synchronized (mPidsSelfLocked) {
7390            for (int i = 0; i < pids.length; i++) {
7391                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7392                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7393                        pr.curProcState;
7394                if (scores != null) {
7395                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7396                }
7397            }
7398        }
7399    }
7400
7401    // =========================================================
7402    // PERMISSIONS
7403    // =========================================================
7404
7405    static class PermissionController extends IPermissionController.Stub {
7406        ActivityManagerService mActivityManagerService;
7407        PermissionController(ActivityManagerService activityManagerService) {
7408            mActivityManagerService = activityManagerService;
7409        }
7410
7411        @Override
7412        public boolean checkPermission(String permission, int pid, int uid) {
7413            return mActivityManagerService.checkPermission(permission, pid,
7414                    uid) == PackageManager.PERMISSION_GRANTED;
7415        }
7416
7417        @Override
7418        public String[] getPackagesForUid(int uid) {
7419            return mActivityManagerService.mContext.getPackageManager()
7420                    .getPackagesForUid(uid);
7421        }
7422
7423        @Override
7424        public boolean isRuntimePermission(String permission) {
7425            try {
7426                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7427                        .getPermissionInfo(permission, 0);
7428                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7429            } catch (NameNotFoundException nnfe) {
7430                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7431            }
7432            return false;
7433        }
7434    }
7435
7436    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7437        @Override
7438        public int checkComponentPermission(String permission, int pid, int uid,
7439                int owningUid, boolean exported) {
7440            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7441                    owningUid, exported);
7442        }
7443
7444        @Override
7445        public Object getAMSLock() {
7446            return ActivityManagerService.this;
7447        }
7448    }
7449
7450    /**
7451     * This can be called with or without the global lock held.
7452     */
7453    int checkComponentPermission(String permission, int pid, int uid,
7454            int owningUid, boolean exported) {
7455        if (pid == MY_PID) {
7456            return PackageManager.PERMISSION_GRANTED;
7457        }
7458        return ActivityManager.checkComponentPermission(permission, uid,
7459                owningUid, exported);
7460    }
7461
7462    /**
7463     * As the only public entry point for permissions checking, this method
7464     * can enforce the semantic that requesting a check on a null global
7465     * permission is automatically denied.  (Internally a null permission
7466     * string is used when calling {@link #checkComponentPermission} in cases
7467     * when only uid-based security is needed.)
7468     *
7469     * This can be called with or without the global lock held.
7470     */
7471    @Override
7472    public int checkPermission(String permission, int pid, int uid) {
7473        if (permission == null) {
7474            return PackageManager.PERMISSION_DENIED;
7475        }
7476        return checkComponentPermission(permission, pid, uid, -1, true);
7477    }
7478
7479    @Override
7480    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7481        if (permission == null) {
7482            return PackageManager.PERMISSION_DENIED;
7483        }
7484
7485        // We might be performing an operation on behalf of an indirect binder
7486        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7487        // client identity accordingly before proceeding.
7488        Identity tlsIdentity = sCallerIdentity.get();
7489        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7490            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7491                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7492            uid = tlsIdentity.uid;
7493            pid = tlsIdentity.pid;
7494        }
7495
7496        return checkComponentPermission(permission, pid, uid, -1, true);
7497    }
7498
7499    /**
7500     * Binder IPC calls go through the public entry point.
7501     * This can be called with or without the global lock held.
7502     */
7503    int checkCallingPermission(String permission) {
7504        return checkPermission(permission,
7505                Binder.getCallingPid(),
7506                UserHandle.getAppId(Binder.getCallingUid()));
7507    }
7508
7509    /**
7510     * This can be called with or without the global lock held.
7511     */
7512    void enforceCallingPermission(String permission, String func) {
7513        if (checkCallingPermission(permission)
7514                == PackageManager.PERMISSION_GRANTED) {
7515            return;
7516        }
7517
7518        String msg = "Permission Denial: " + func + " from pid="
7519                + Binder.getCallingPid()
7520                + ", uid=" + Binder.getCallingUid()
7521                + " requires " + permission;
7522        Slog.w(TAG, msg);
7523        throw new SecurityException(msg);
7524    }
7525
7526    /**
7527     * Determine if UID is holding permissions required to access {@link Uri} in
7528     * the given {@link ProviderInfo}. Final permission checking is always done
7529     * in {@link ContentProvider}.
7530     */
7531    private final boolean checkHoldingPermissionsLocked(
7532            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7533        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7534                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7535        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7536            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7537                    != PERMISSION_GRANTED) {
7538                return false;
7539            }
7540        }
7541        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7542    }
7543
7544    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7545            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7546        if (pi.applicationInfo.uid == uid) {
7547            return true;
7548        } else if (!pi.exported) {
7549            return false;
7550        }
7551
7552        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7553        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7554        try {
7555            // check if target holds top-level <provider> permissions
7556            if (!readMet && pi.readPermission != null && considerUidPermissions
7557                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7558                readMet = true;
7559            }
7560            if (!writeMet && pi.writePermission != null && considerUidPermissions
7561                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7562                writeMet = true;
7563            }
7564
7565            // track if unprotected read/write is allowed; any denied
7566            // <path-permission> below removes this ability
7567            boolean allowDefaultRead = pi.readPermission == null;
7568            boolean allowDefaultWrite = pi.writePermission == null;
7569
7570            // check if target holds any <path-permission> that match uri
7571            final PathPermission[] pps = pi.pathPermissions;
7572            if (pps != null) {
7573                final String path = grantUri.uri.getPath();
7574                int i = pps.length;
7575                while (i > 0 && (!readMet || !writeMet)) {
7576                    i--;
7577                    PathPermission pp = pps[i];
7578                    if (pp.match(path)) {
7579                        if (!readMet) {
7580                            final String pprperm = pp.getReadPermission();
7581                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7582                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7583                                    + ": match=" + pp.match(path)
7584                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7585                            if (pprperm != null) {
7586                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7587                                        == PERMISSION_GRANTED) {
7588                                    readMet = true;
7589                                } else {
7590                                    allowDefaultRead = false;
7591                                }
7592                            }
7593                        }
7594                        if (!writeMet) {
7595                            final String ppwperm = pp.getWritePermission();
7596                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7597                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7598                                    + ": match=" + pp.match(path)
7599                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7600                            if (ppwperm != null) {
7601                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7602                                        == PERMISSION_GRANTED) {
7603                                    writeMet = true;
7604                                } else {
7605                                    allowDefaultWrite = false;
7606                                }
7607                            }
7608                        }
7609                    }
7610                }
7611            }
7612
7613            // grant unprotected <provider> read/write, if not blocked by
7614            // <path-permission> above
7615            if (allowDefaultRead) readMet = true;
7616            if (allowDefaultWrite) writeMet = true;
7617
7618        } catch (RemoteException e) {
7619            return false;
7620        }
7621
7622        return readMet && writeMet;
7623    }
7624
7625    public int getAppStartMode(int uid, String packageName) {
7626        synchronized (this) {
7627            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7628        }
7629    }
7630
7631    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7632            boolean allowWhenForeground) {
7633        UidRecord uidRec = mActiveUids.get(uid);
7634        if (!mLenientBackgroundCheck) {
7635            if (!allowWhenForeground || uidRec == null
7636                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7637                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7638                        packageName) != AppOpsManager.MODE_ALLOWED) {
7639                    return ActivityManager.APP_START_MODE_DELAYED;
7640                }
7641            }
7642
7643        } else if (uidRec == null || uidRec.idle) {
7644            if (callingPid >= 0) {
7645                ProcessRecord proc;
7646                synchronized (mPidsSelfLocked) {
7647                    proc = mPidsSelfLocked.get(callingPid);
7648                }
7649                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7650                    // Whoever is instigating this is in the foreground, so we will allow it
7651                    // to go through.
7652                    return ActivityManager.APP_START_MODE_NORMAL;
7653                }
7654            }
7655            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7656                    != AppOpsManager.MODE_ALLOWED) {
7657                return ActivityManager.APP_START_MODE_DELAYED;
7658            }
7659        }
7660        return ActivityManager.APP_START_MODE_NORMAL;
7661    }
7662
7663    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7664        ProviderInfo pi = null;
7665        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7666        if (cpr != null) {
7667            pi = cpr.info;
7668        } else {
7669            try {
7670                pi = AppGlobals.getPackageManager().resolveContentProvider(
7671                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7672            } catch (RemoteException ex) {
7673            }
7674        }
7675        return pi;
7676    }
7677
7678    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7679        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7680        if (targetUris != null) {
7681            return targetUris.get(grantUri);
7682        }
7683        return null;
7684    }
7685
7686    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7687            String targetPkg, int targetUid, GrantUri grantUri) {
7688        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7689        if (targetUris == null) {
7690            targetUris = Maps.newArrayMap();
7691            mGrantedUriPermissions.put(targetUid, targetUris);
7692        }
7693
7694        UriPermission perm = targetUris.get(grantUri);
7695        if (perm == null) {
7696            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7697            targetUris.put(grantUri, perm);
7698        }
7699
7700        return perm;
7701    }
7702
7703    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7704            final int modeFlags) {
7705        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7706        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7707                : UriPermission.STRENGTH_OWNED;
7708
7709        // Root gets to do everything.
7710        if (uid == 0) {
7711            return true;
7712        }
7713
7714        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7715        if (perms == null) return false;
7716
7717        // First look for exact match
7718        final UriPermission exactPerm = perms.get(grantUri);
7719        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7720            return true;
7721        }
7722
7723        // No exact match, look for prefixes
7724        final int N = perms.size();
7725        for (int i = 0; i < N; i++) {
7726            final UriPermission perm = perms.valueAt(i);
7727            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7728                    && perm.getStrength(modeFlags) >= minStrength) {
7729                return true;
7730            }
7731        }
7732
7733        return false;
7734    }
7735
7736    /**
7737     * @param uri This uri must NOT contain an embedded userId.
7738     * @param userId The userId in which the uri is to be resolved.
7739     */
7740    @Override
7741    public int checkUriPermission(Uri uri, int pid, int uid,
7742            final int modeFlags, int userId, IBinder callerToken) {
7743        enforceNotIsolatedCaller("checkUriPermission");
7744
7745        // Another redirected-binder-call permissions check as in
7746        // {@link checkPermissionWithToken}.
7747        Identity tlsIdentity = sCallerIdentity.get();
7748        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7749            uid = tlsIdentity.uid;
7750            pid = tlsIdentity.pid;
7751        }
7752
7753        // Our own process gets to do everything.
7754        if (pid == MY_PID) {
7755            return PackageManager.PERMISSION_GRANTED;
7756        }
7757        synchronized (this) {
7758            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7759                    ? PackageManager.PERMISSION_GRANTED
7760                    : PackageManager.PERMISSION_DENIED;
7761        }
7762    }
7763
7764    /**
7765     * Check if the targetPkg can be granted permission to access uri by
7766     * the callingUid using the given modeFlags.  Throws a security exception
7767     * if callingUid is not allowed to do this.  Returns the uid of the target
7768     * if the URI permission grant should be performed; returns -1 if it is not
7769     * needed (for example targetPkg already has permission to access the URI).
7770     * If you already know the uid of the target, you can supply it in
7771     * lastTargetUid else set that to -1.
7772     */
7773    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7774            final int modeFlags, int lastTargetUid) {
7775        if (!Intent.isAccessUriMode(modeFlags)) {
7776            return -1;
7777        }
7778
7779        if (targetPkg != null) {
7780            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7781                    "Checking grant " + targetPkg + " permission to " + grantUri);
7782        }
7783
7784        final IPackageManager pm = AppGlobals.getPackageManager();
7785
7786        // If this is not a content: uri, we can't do anything with it.
7787        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7788            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7789                    "Can't grant URI permission for non-content URI: " + grantUri);
7790            return -1;
7791        }
7792
7793        final String authority = grantUri.uri.getAuthority();
7794        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7795        if (pi == null) {
7796            Slog.w(TAG, "No content provider found for permission check: " +
7797                    grantUri.uri.toSafeString());
7798            return -1;
7799        }
7800
7801        int targetUid = lastTargetUid;
7802        if (targetUid < 0 && targetPkg != null) {
7803            try {
7804                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7805                        UserHandle.getUserId(callingUid));
7806                if (targetUid < 0) {
7807                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7808                            "Can't grant URI permission no uid for: " + targetPkg);
7809                    return -1;
7810                }
7811            } catch (RemoteException ex) {
7812                return -1;
7813            }
7814        }
7815
7816        if (targetUid >= 0) {
7817            // First...  does the target actually need this permission?
7818            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7819                // No need to grant the target this permission.
7820                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7821                        "Target " + targetPkg + " already has full permission to " + grantUri);
7822                return -1;
7823            }
7824        } else {
7825            // First...  there is no target package, so can anyone access it?
7826            boolean allowed = pi.exported;
7827            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7828                if (pi.readPermission != null) {
7829                    allowed = false;
7830                }
7831            }
7832            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7833                if (pi.writePermission != null) {
7834                    allowed = false;
7835                }
7836            }
7837            if (allowed) {
7838                return -1;
7839            }
7840        }
7841
7842        /* There is a special cross user grant if:
7843         * - The target is on another user.
7844         * - Apps on the current user can access the uri without any uid permissions.
7845         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7846         * grant uri permissions.
7847         */
7848        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7849                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7850                modeFlags, false /*without considering the uid permissions*/);
7851
7852        // Second...  is the provider allowing granting of URI permissions?
7853        if (!specialCrossUserGrant) {
7854            if (!pi.grantUriPermissions) {
7855                throw new SecurityException("Provider " + pi.packageName
7856                        + "/" + pi.name
7857                        + " does not allow granting of Uri permissions (uri "
7858                        + grantUri + ")");
7859            }
7860            if (pi.uriPermissionPatterns != null) {
7861                final int N = pi.uriPermissionPatterns.length;
7862                boolean allowed = false;
7863                for (int i=0; i<N; i++) {
7864                    if (pi.uriPermissionPatterns[i] != null
7865                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7866                        allowed = true;
7867                        break;
7868                    }
7869                }
7870                if (!allowed) {
7871                    throw new SecurityException("Provider " + pi.packageName
7872                            + "/" + pi.name
7873                            + " does not allow granting of permission to path of Uri "
7874                            + grantUri);
7875                }
7876            }
7877        }
7878
7879        // Third...  does the caller itself have permission to access
7880        // this uri?
7881        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7882            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7883                // Require they hold a strong enough Uri permission
7884                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7885                    throw new SecurityException("Uid " + callingUid
7886                            + " does not have permission to uri " + grantUri);
7887                }
7888            }
7889        }
7890        return targetUid;
7891    }
7892
7893    /**
7894     * @param uri This uri must NOT contain an embedded userId.
7895     * @param userId The userId in which the uri is to be resolved.
7896     */
7897    @Override
7898    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7899            final int modeFlags, int userId) {
7900        enforceNotIsolatedCaller("checkGrantUriPermission");
7901        synchronized(this) {
7902            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7903                    new GrantUri(userId, uri, false), modeFlags, -1);
7904        }
7905    }
7906
7907    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7908            final int modeFlags, UriPermissionOwner owner) {
7909        if (!Intent.isAccessUriMode(modeFlags)) {
7910            return;
7911        }
7912
7913        // So here we are: the caller has the assumed permission
7914        // to the uri, and the target doesn't.  Let's now give this to
7915        // the target.
7916
7917        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7918                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7919
7920        final String authority = grantUri.uri.getAuthority();
7921        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7922        if (pi == null) {
7923            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7924            return;
7925        }
7926
7927        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7928            grantUri.prefix = true;
7929        }
7930        final UriPermission perm = findOrCreateUriPermissionLocked(
7931                pi.packageName, targetPkg, targetUid, grantUri);
7932        perm.grantModes(modeFlags, owner);
7933    }
7934
7935    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7936            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7937        if (targetPkg == null) {
7938            throw new NullPointerException("targetPkg");
7939        }
7940        int targetUid;
7941        final IPackageManager pm = AppGlobals.getPackageManager();
7942        try {
7943            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7944        } catch (RemoteException ex) {
7945            return;
7946        }
7947
7948        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7949                targetUid);
7950        if (targetUid < 0) {
7951            return;
7952        }
7953
7954        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7955                owner);
7956    }
7957
7958    static class NeededUriGrants extends ArrayList<GrantUri> {
7959        final String targetPkg;
7960        final int targetUid;
7961        final int flags;
7962
7963        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7964            this.targetPkg = targetPkg;
7965            this.targetUid = targetUid;
7966            this.flags = flags;
7967        }
7968    }
7969
7970    /**
7971     * Like checkGrantUriPermissionLocked, but takes an Intent.
7972     */
7973    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7974            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7975        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7976                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7977                + " clip=" + (intent != null ? intent.getClipData() : null)
7978                + " from " + intent + "; flags=0x"
7979                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7980
7981        if (targetPkg == null) {
7982            throw new NullPointerException("targetPkg");
7983        }
7984
7985        if (intent == null) {
7986            return null;
7987        }
7988        Uri data = intent.getData();
7989        ClipData clip = intent.getClipData();
7990        if (data == null && clip == null) {
7991            return null;
7992        }
7993        // Default userId for uris in the intent (if they don't specify it themselves)
7994        int contentUserHint = intent.getContentUserHint();
7995        if (contentUserHint == UserHandle.USER_CURRENT) {
7996            contentUserHint = UserHandle.getUserId(callingUid);
7997        }
7998        final IPackageManager pm = AppGlobals.getPackageManager();
7999        int targetUid;
8000        if (needed != null) {
8001            targetUid = needed.targetUid;
8002        } else {
8003            try {
8004                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8005                        targetUserId);
8006            } catch (RemoteException ex) {
8007                return null;
8008            }
8009            if (targetUid < 0) {
8010                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8011                        "Can't grant URI permission no uid for: " + targetPkg
8012                        + " on user " + targetUserId);
8013                return null;
8014            }
8015        }
8016        if (data != null) {
8017            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8018            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8019                    targetUid);
8020            if (targetUid > 0) {
8021                if (needed == null) {
8022                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8023                }
8024                needed.add(grantUri);
8025            }
8026        }
8027        if (clip != null) {
8028            for (int i=0; i<clip.getItemCount(); i++) {
8029                Uri uri = clip.getItemAt(i).getUri();
8030                if (uri != null) {
8031                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8032                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8033                            targetUid);
8034                    if (targetUid > 0) {
8035                        if (needed == null) {
8036                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8037                        }
8038                        needed.add(grantUri);
8039                    }
8040                } else {
8041                    Intent clipIntent = clip.getItemAt(i).getIntent();
8042                    if (clipIntent != null) {
8043                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8044                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8045                        if (newNeeded != null) {
8046                            needed = newNeeded;
8047                        }
8048                    }
8049                }
8050            }
8051        }
8052
8053        return needed;
8054    }
8055
8056    /**
8057     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8058     */
8059    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8060            UriPermissionOwner owner) {
8061        if (needed != null) {
8062            for (int i=0; i<needed.size(); i++) {
8063                GrantUri grantUri = needed.get(i);
8064                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8065                        grantUri, needed.flags, owner);
8066            }
8067        }
8068    }
8069
8070    void grantUriPermissionFromIntentLocked(int callingUid,
8071            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8072        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8073                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8074        if (needed == null) {
8075            return;
8076        }
8077
8078        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8079    }
8080
8081    /**
8082     * @param uri This uri must NOT contain an embedded userId.
8083     * @param userId The userId in which the uri is to be resolved.
8084     */
8085    @Override
8086    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8087            final int modeFlags, int userId) {
8088        enforceNotIsolatedCaller("grantUriPermission");
8089        GrantUri grantUri = new GrantUri(userId, uri, false);
8090        synchronized(this) {
8091            final ProcessRecord r = getRecordForAppLocked(caller);
8092            if (r == null) {
8093                throw new SecurityException("Unable to find app for caller "
8094                        + caller
8095                        + " when granting permission to uri " + grantUri);
8096            }
8097            if (targetPkg == null) {
8098                throw new IllegalArgumentException("null target");
8099            }
8100            if (grantUri == null) {
8101                throw new IllegalArgumentException("null uri");
8102            }
8103
8104            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8105                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8106                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8107                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8108
8109            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8110                    UserHandle.getUserId(r.uid));
8111        }
8112    }
8113
8114    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8115        if (perm.modeFlags == 0) {
8116            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8117                    perm.targetUid);
8118            if (perms != null) {
8119                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8120                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8121
8122                perms.remove(perm.uri);
8123                if (perms.isEmpty()) {
8124                    mGrantedUriPermissions.remove(perm.targetUid);
8125                }
8126            }
8127        }
8128    }
8129
8130    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8131        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8132                "Revoking all granted permissions to " + grantUri);
8133
8134        final IPackageManager pm = AppGlobals.getPackageManager();
8135        final String authority = grantUri.uri.getAuthority();
8136        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8137        if (pi == null) {
8138            Slog.w(TAG, "No content provider found for permission revoke: "
8139                    + grantUri.toSafeString());
8140            return;
8141        }
8142
8143        // Does the caller have this permission on the URI?
8144        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8145            // If they don't have direct access to the URI, then revoke any
8146            // ownerless URI permissions that have been granted to them.
8147            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8148            if (perms != null) {
8149                boolean persistChanged = false;
8150                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8151                    final UriPermission perm = it.next();
8152                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8153                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8154                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8155                                "Revoking non-owned " + perm.targetUid
8156                                + " permission to " + perm.uri);
8157                        persistChanged |= perm.revokeModes(
8158                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8159                        if (perm.modeFlags == 0) {
8160                            it.remove();
8161                        }
8162                    }
8163                }
8164                if (perms.isEmpty()) {
8165                    mGrantedUriPermissions.remove(callingUid);
8166                }
8167                if (persistChanged) {
8168                    schedulePersistUriGrants();
8169                }
8170            }
8171            return;
8172        }
8173
8174        boolean persistChanged = false;
8175
8176        // Go through all of the permissions and remove any that match.
8177        int N = mGrantedUriPermissions.size();
8178        for (int i = 0; i < N; i++) {
8179            final int targetUid = mGrantedUriPermissions.keyAt(i);
8180            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8181
8182            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8183                final UriPermission perm = it.next();
8184                if (perm.uri.sourceUserId == grantUri.sourceUserId
8185                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8186                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8187                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8188                    persistChanged |= perm.revokeModes(
8189                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8190                    if (perm.modeFlags == 0) {
8191                        it.remove();
8192                    }
8193                }
8194            }
8195
8196            if (perms.isEmpty()) {
8197                mGrantedUriPermissions.remove(targetUid);
8198                N--;
8199                i--;
8200            }
8201        }
8202
8203        if (persistChanged) {
8204            schedulePersistUriGrants();
8205        }
8206    }
8207
8208    /**
8209     * @param uri This uri must NOT contain an embedded userId.
8210     * @param userId The userId in which the uri is to be resolved.
8211     */
8212    @Override
8213    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8214            int userId) {
8215        enforceNotIsolatedCaller("revokeUriPermission");
8216        synchronized(this) {
8217            final ProcessRecord r = getRecordForAppLocked(caller);
8218            if (r == null) {
8219                throw new SecurityException("Unable to find app for caller "
8220                        + caller
8221                        + " when revoking permission to uri " + uri);
8222            }
8223            if (uri == null) {
8224                Slog.w(TAG, "revokeUriPermission: null uri");
8225                return;
8226            }
8227
8228            if (!Intent.isAccessUriMode(modeFlags)) {
8229                return;
8230            }
8231
8232            final String authority = uri.getAuthority();
8233            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8234            if (pi == null) {
8235                Slog.w(TAG, "No content provider found for permission revoke: "
8236                        + uri.toSafeString());
8237                return;
8238            }
8239
8240            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8241        }
8242    }
8243
8244    /**
8245     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8246     * given package.
8247     *
8248     * @param packageName Package name to match, or {@code null} to apply to all
8249     *            packages.
8250     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8251     *            to all users.
8252     * @param persistable If persistable grants should be removed.
8253     */
8254    private void removeUriPermissionsForPackageLocked(
8255            String packageName, int userHandle, boolean persistable) {
8256        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8257            throw new IllegalArgumentException("Must narrow by either package or user");
8258        }
8259
8260        boolean persistChanged = false;
8261
8262        int N = mGrantedUriPermissions.size();
8263        for (int i = 0; i < N; i++) {
8264            final int targetUid = mGrantedUriPermissions.keyAt(i);
8265            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8266
8267            // Only inspect grants matching user
8268            if (userHandle == UserHandle.USER_ALL
8269                    || userHandle == UserHandle.getUserId(targetUid)) {
8270                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8271                    final UriPermission perm = it.next();
8272
8273                    // Only inspect grants matching package
8274                    if (packageName == null || perm.sourcePkg.equals(packageName)
8275                            || perm.targetPkg.equals(packageName)) {
8276                        persistChanged |= perm.revokeModes(persistable
8277                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8278
8279                        // Only remove when no modes remain; any persisted grants
8280                        // will keep this alive.
8281                        if (perm.modeFlags == 0) {
8282                            it.remove();
8283                        }
8284                    }
8285                }
8286
8287                if (perms.isEmpty()) {
8288                    mGrantedUriPermissions.remove(targetUid);
8289                    N--;
8290                    i--;
8291                }
8292            }
8293        }
8294
8295        if (persistChanged) {
8296            schedulePersistUriGrants();
8297        }
8298    }
8299
8300    @Override
8301    public IBinder newUriPermissionOwner(String name) {
8302        enforceNotIsolatedCaller("newUriPermissionOwner");
8303        synchronized(this) {
8304            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8305            return owner.getExternalTokenLocked();
8306        }
8307    }
8308
8309    @Override
8310    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8311        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8312        synchronized(this) {
8313            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8314            if (r == null) {
8315                throw new IllegalArgumentException("Activity does not exist; token="
8316                        + activityToken);
8317            }
8318            return r.getUriPermissionsLocked().getExternalTokenLocked();
8319        }
8320    }
8321    /**
8322     * @param uri This uri must NOT contain an embedded userId.
8323     * @param sourceUserId The userId in which the uri is to be resolved.
8324     * @param targetUserId The userId of the app that receives the grant.
8325     */
8326    @Override
8327    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8328            final int modeFlags, int sourceUserId, int targetUserId) {
8329        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8330                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8331                "grantUriPermissionFromOwner", null);
8332        synchronized(this) {
8333            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8334            if (owner == null) {
8335                throw new IllegalArgumentException("Unknown owner: " + token);
8336            }
8337            if (fromUid != Binder.getCallingUid()) {
8338                if (Binder.getCallingUid() != Process.myUid()) {
8339                    // Only system code can grant URI permissions on behalf
8340                    // of other users.
8341                    throw new SecurityException("nice try");
8342                }
8343            }
8344            if (targetPkg == null) {
8345                throw new IllegalArgumentException("null target");
8346            }
8347            if (uri == null) {
8348                throw new IllegalArgumentException("null uri");
8349            }
8350
8351            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8352                    modeFlags, owner, targetUserId);
8353        }
8354    }
8355
8356    /**
8357     * @param uri This uri must NOT contain an embedded userId.
8358     * @param userId The userId in which the uri is to be resolved.
8359     */
8360    @Override
8361    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8362        synchronized(this) {
8363            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8364            if (owner == null) {
8365                throw new IllegalArgumentException("Unknown owner: " + token);
8366            }
8367
8368            if (uri == null) {
8369                owner.removeUriPermissionsLocked(mode);
8370            } else {
8371                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8372            }
8373        }
8374    }
8375
8376    private void schedulePersistUriGrants() {
8377        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8378            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8379                    10 * DateUtils.SECOND_IN_MILLIS);
8380        }
8381    }
8382
8383    private void writeGrantedUriPermissions() {
8384        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8385
8386        // Snapshot permissions so we can persist without lock
8387        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8388        synchronized (this) {
8389            final int size = mGrantedUriPermissions.size();
8390            for (int i = 0; i < size; i++) {
8391                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8392                for (UriPermission perm : perms.values()) {
8393                    if (perm.persistedModeFlags != 0) {
8394                        persist.add(perm.snapshot());
8395                    }
8396                }
8397            }
8398        }
8399
8400        FileOutputStream fos = null;
8401        try {
8402            fos = mGrantFile.startWrite();
8403
8404            XmlSerializer out = new FastXmlSerializer();
8405            out.setOutput(fos, StandardCharsets.UTF_8.name());
8406            out.startDocument(null, true);
8407            out.startTag(null, TAG_URI_GRANTS);
8408            for (UriPermission.Snapshot perm : persist) {
8409                out.startTag(null, TAG_URI_GRANT);
8410                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8411                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8412                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8413                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8414                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8415                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8416                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8417                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8418                out.endTag(null, TAG_URI_GRANT);
8419            }
8420            out.endTag(null, TAG_URI_GRANTS);
8421            out.endDocument();
8422
8423            mGrantFile.finishWrite(fos);
8424        } catch (IOException e) {
8425            if (fos != null) {
8426                mGrantFile.failWrite(fos);
8427            }
8428        }
8429    }
8430
8431    private void readGrantedUriPermissionsLocked() {
8432        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8433
8434        final long now = System.currentTimeMillis();
8435
8436        FileInputStream fis = null;
8437        try {
8438            fis = mGrantFile.openRead();
8439            final XmlPullParser in = Xml.newPullParser();
8440            in.setInput(fis, StandardCharsets.UTF_8.name());
8441
8442            int type;
8443            while ((type = in.next()) != END_DOCUMENT) {
8444                final String tag = in.getName();
8445                if (type == START_TAG) {
8446                    if (TAG_URI_GRANT.equals(tag)) {
8447                        final int sourceUserId;
8448                        final int targetUserId;
8449                        final int userHandle = readIntAttribute(in,
8450                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8451                        if (userHandle != UserHandle.USER_NULL) {
8452                            // For backwards compatibility.
8453                            sourceUserId = userHandle;
8454                            targetUserId = userHandle;
8455                        } else {
8456                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8457                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8458                        }
8459                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8460                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8461                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8462                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8463                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8464                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8465
8466                        // Sanity check that provider still belongs to source package
8467                        final ProviderInfo pi = getProviderInfoLocked(
8468                                uri.getAuthority(), sourceUserId);
8469                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8470                            int targetUid = -1;
8471                            try {
8472                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8473                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8474                            } catch (RemoteException e) {
8475                            }
8476                            if (targetUid != -1) {
8477                                final UriPermission perm = findOrCreateUriPermissionLocked(
8478                                        sourcePkg, targetPkg, targetUid,
8479                                        new GrantUri(sourceUserId, uri, prefix));
8480                                perm.initPersistedModes(modeFlags, createdTime);
8481                            }
8482                        } else {
8483                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8484                                    + " but instead found " + pi);
8485                        }
8486                    }
8487                }
8488            }
8489        } catch (FileNotFoundException e) {
8490            // Missing grants is okay
8491        } catch (IOException e) {
8492            Slog.wtf(TAG, "Failed reading Uri grants", e);
8493        } catch (XmlPullParserException e) {
8494            Slog.wtf(TAG, "Failed reading Uri grants", e);
8495        } finally {
8496            IoUtils.closeQuietly(fis);
8497        }
8498    }
8499
8500    /**
8501     * @param uri This uri must NOT contain an embedded userId.
8502     * @param userId The userId in which the uri is to be resolved.
8503     */
8504    @Override
8505    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8506        enforceNotIsolatedCaller("takePersistableUriPermission");
8507
8508        Preconditions.checkFlagsArgument(modeFlags,
8509                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8510
8511        synchronized (this) {
8512            final int callingUid = Binder.getCallingUid();
8513            boolean persistChanged = false;
8514            GrantUri grantUri = new GrantUri(userId, uri, false);
8515
8516            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8517                    new GrantUri(userId, uri, false));
8518            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8519                    new GrantUri(userId, uri, true));
8520
8521            final boolean exactValid = (exactPerm != null)
8522                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8523            final boolean prefixValid = (prefixPerm != null)
8524                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8525
8526            if (!(exactValid || prefixValid)) {
8527                throw new SecurityException("No persistable permission grants found for UID "
8528                        + callingUid + " and Uri " + grantUri.toSafeString());
8529            }
8530
8531            if (exactValid) {
8532                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8533            }
8534            if (prefixValid) {
8535                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8536            }
8537
8538            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8539
8540            if (persistChanged) {
8541                schedulePersistUriGrants();
8542            }
8543        }
8544    }
8545
8546    /**
8547     * @param uri This uri must NOT contain an embedded userId.
8548     * @param userId The userId in which the uri is to be resolved.
8549     */
8550    @Override
8551    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8552        enforceNotIsolatedCaller("releasePersistableUriPermission");
8553
8554        Preconditions.checkFlagsArgument(modeFlags,
8555                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8556
8557        synchronized (this) {
8558            final int callingUid = Binder.getCallingUid();
8559            boolean persistChanged = false;
8560
8561            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8562                    new GrantUri(userId, uri, false));
8563            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8564                    new GrantUri(userId, uri, true));
8565            if (exactPerm == null && prefixPerm == null) {
8566                throw new SecurityException("No permission grants found for UID " + callingUid
8567                        + " and Uri " + uri.toSafeString());
8568            }
8569
8570            if (exactPerm != null) {
8571                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8572                removeUriPermissionIfNeededLocked(exactPerm);
8573            }
8574            if (prefixPerm != null) {
8575                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8576                removeUriPermissionIfNeededLocked(prefixPerm);
8577            }
8578
8579            if (persistChanged) {
8580                schedulePersistUriGrants();
8581            }
8582        }
8583    }
8584
8585    /**
8586     * Prune any older {@link UriPermission} for the given UID until outstanding
8587     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8588     *
8589     * @return if any mutations occured that require persisting.
8590     */
8591    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8592        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8593        if (perms == null) return false;
8594        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8595
8596        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8597        for (UriPermission perm : perms.values()) {
8598            if (perm.persistedModeFlags != 0) {
8599                persisted.add(perm);
8600            }
8601        }
8602
8603        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8604        if (trimCount <= 0) return false;
8605
8606        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8607        for (int i = 0; i < trimCount; i++) {
8608            final UriPermission perm = persisted.get(i);
8609
8610            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8611                    "Trimming grant created at " + perm.persistedCreateTime);
8612
8613            perm.releasePersistableModes(~0);
8614            removeUriPermissionIfNeededLocked(perm);
8615        }
8616
8617        return true;
8618    }
8619
8620    @Override
8621    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8622            String packageName, boolean incoming) {
8623        enforceNotIsolatedCaller("getPersistedUriPermissions");
8624        Preconditions.checkNotNull(packageName, "packageName");
8625
8626        final int callingUid = Binder.getCallingUid();
8627        final IPackageManager pm = AppGlobals.getPackageManager();
8628        try {
8629            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8630                    UserHandle.getUserId(callingUid));
8631            if (packageUid != callingUid) {
8632                throw new SecurityException(
8633                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8634            }
8635        } catch (RemoteException e) {
8636            throw new SecurityException("Failed to verify package name ownership");
8637        }
8638
8639        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8640        synchronized (this) {
8641            if (incoming) {
8642                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8643                        callingUid);
8644                if (perms == null) {
8645                    Slog.w(TAG, "No permission grants found for " + packageName);
8646                } else {
8647                    for (UriPermission perm : perms.values()) {
8648                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8649                            result.add(perm.buildPersistedPublicApiObject());
8650                        }
8651                    }
8652                }
8653            } else {
8654                final int size = mGrantedUriPermissions.size();
8655                for (int i = 0; i < size; i++) {
8656                    final ArrayMap<GrantUri, UriPermission> perms =
8657                            mGrantedUriPermissions.valueAt(i);
8658                    for (UriPermission perm : perms.values()) {
8659                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8660                            result.add(perm.buildPersistedPublicApiObject());
8661                        }
8662                    }
8663                }
8664            }
8665        }
8666        return new ParceledListSlice<android.content.UriPermission>(result);
8667    }
8668
8669    @Override
8670    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8671            String packageName, int userId) {
8672        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8673                "getGrantedUriPermissions");
8674
8675        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8676        synchronized (this) {
8677            final int size = mGrantedUriPermissions.size();
8678            for (int i = 0; i < size; i++) {
8679                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8680                for (UriPermission perm : perms.values()) {
8681                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8682                            && perm.persistedModeFlags != 0) {
8683                        result.add(perm.buildPersistedPublicApiObject());
8684                    }
8685                }
8686            }
8687        }
8688        return new ParceledListSlice<android.content.UriPermission>(result);
8689    }
8690
8691    @Override
8692    public void clearGrantedUriPermissions(String packageName, int userId) {
8693        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8694                "clearGrantedUriPermissions");
8695        removeUriPermissionsForPackageLocked(packageName, userId, true);
8696    }
8697
8698    @Override
8699    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8700        synchronized (this) {
8701            ProcessRecord app =
8702                who != null ? getRecordForAppLocked(who) : null;
8703            if (app == null) return;
8704
8705            Message msg = Message.obtain();
8706            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8707            msg.obj = app;
8708            msg.arg1 = waiting ? 1 : 0;
8709            mUiHandler.sendMessage(msg);
8710        }
8711    }
8712
8713    @Override
8714    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8715        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8716        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8717        outInfo.availMem = Process.getFreeMemory();
8718        outInfo.totalMem = Process.getTotalMemory();
8719        outInfo.threshold = homeAppMem;
8720        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8721        outInfo.hiddenAppThreshold = cachedAppMem;
8722        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8723                ProcessList.SERVICE_ADJ);
8724        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8725                ProcessList.VISIBLE_APP_ADJ);
8726        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8727                ProcessList.FOREGROUND_APP_ADJ);
8728    }
8729
8730    // =========================================================
8731    // TASK MANAGEMENT
8732    // =========================================================
8733
8734    @Override
8735    public List<IAppTask> getAppTasks(String callingPackage) {
8736        int callingUid = Binder.getCallingUid();
8737        long ident = Binder.clearCallingIdentity();
8738
8739        synchronized(this) {
8740            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8741            try {
8742                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8743
8744                final int N = mRecentTasks.size();
8745                for (int i = 0; i < N; i++) {
8746                    TaskRecord tr = mRecentTasks.get(i);
8747                    // Skip tasks that do not match the caller.  We don't need to verify
8748                    // callingPackage, because we are also limiting to callingUid and know
8749                    // that will limit to the correct security sandbox.
8750                    if (tr.effectiveUid != callingUid) {
8751                        continue;
8752                    }
8753                    Intent intent = tr.getBaseIntent();
8754                    if (intent == null ||
8755                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8756                        continue;
8757                    }
8758                    ActivityManager.RecentTaskInfo taskInfo =
8759                            createRecentTaskInfoFromTaskRecord(tr);
8760                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8761                    list.add(taskImpl);
8762                }
8763            } finally {
8764                Binder.restoreCallingIdentity(ident);
8765            }
8766            return list;
8767        }
8768    }
8769
8770    @Override
8771    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8772        final int callingUid = Binder.getCallingUid();
8773        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8774
8775        synchronized(this) {
8776            if (DEBUG_ALL) Slog.v(
8777                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8778
8779            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8780                    callingUid);
8781
8782            // TODO: Improve with MRU list from all ActivityStacks.
8783            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8784        }
8785
8786        return list;
8787    }
8788
8789    /**
8790     * Creates a new RecentTaskInfo from a TaskRecord.
8791     */
8792    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8793        // Update the task description to reflect any changes in the task stack
8794        tr.updateTaskDescription();
8795
8796        // Compose the recent task info
8797        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8798        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8799        rti.persistentId = tr.taskId;
8800        rti.baseIntent = new Intent(tr.getBaseIntent());
8801        rti.origActivity = tr.origActivity;
8802        rti.realActivity = tr.realActivity;
8803        rti.description = tr.lastDescription;
8804        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8805        rti.userId = tr.userId;
8806        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8807        rti.firstActiveTime = tr.firstActiveTime;
8808        rti.lastActiveTime = tr.lastActiveTime;
8809        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8810        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8811        rti.numActivities = 0;
8812        if (tr.mBounds != null) {
8813            rti.bounds = new Rect(tr.mBounds);
8814        }
8815        rti.isDockable = tr.canGoInDockedStack();
8816        rti.resizeMode = tr.mResizeMode;
8817
8818        ActivityRecord base = null;
8819        ActivityRecord top = null;
8820        ActivityRecord tmp;
8821
8822        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8823            tmp = tr.mActivities.get(i);
8824            if (tmp.finishing) {
8825                continue;
8826            }
8827            base = tmp;
8828            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8829                top = base;
8830            }
8831            rti.numActivities++;
8832        }
8833
8834        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8835        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8836
8837        return rti;
8838    }
8839
8840    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8841        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8842                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8843        if (!allowed) {
8844            if (checkPermission(android.Manifest.permission.GET_TASKS,
8845                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8846                // Temporary compatibility: some existing apps on the system image may
8847                // still be requesting the old permission and not switched to the new
8848                // one; if so, we'll still allow them full access.  This means we need
8849                // to see if they are holding the old permission and are a system app.
8850                try {
8851                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8852                        allowed = true;
8853                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8854                                + " is using old GET_TASKS but privileged; allowing");
8855                    }
8856                } catch (RemoteException e) {
8857                }
8858            }
8859        }
8860        if (!allowed) {
8861            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8862                    + " does not hold REAL_GET_TASKS; limiting output");
8863        }
8864        return allowed;
8865    }
8866
8867    @Override
8868    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8869        final int callingUid = Binder.getCallingUid();
8870        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8871                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8872
8873        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8874        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8875        synchronized (this) {
8876            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8877                    callingUid);
8878            final boolean detailed = checkCallingPermission(
8879                    android.Manifest.permission.GET_DETAILED_TASKS)
8880                    == PackageManager.PERMISSION_GRANTED;
8881
8882            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8883                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8884                return Collections.emptyList();
8885            }
8886            mRecentTasks.loadUserRecentsLocked(userId);
8887
8888            final int recentsCount = mRecentTasks.size();
8889            ArrayList<ActivityManager.RecentTaskInfo> res =
8890                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8891
8892            final Set<Integer> includedUsers;
8893            if (includeProfiles) {
8894                includedUsers = mUserController.getProfileIds(userId);
8895            } else {
8896                includedUsers = new HashSet<>();
8897            }
8898            includedUsers.add(Integer.valueOf(userId));
8899
8900            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8901                TaskRecord tr = mRecentTasks.get(i);
8902                // Only add calling user or related users recent tasks
8903                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8904                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8905                    continue;
8906                }
8907
8908                if (tr.realActivitySuspended) {
8909                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8910                    continue;
8911                }
8912
8913                // Return the entry if desired by the caller.  We always return
8914                // the first entry, because callers always expect this to be the
8915                // foreground app.  We may filter others if the caller has
8916                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8917                // we should exclude the entry.
8918
8919                if (i == 0
8920                        || withExcluded
8921                        || (tr.intent == null)
8922                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8923                                == 0)) {
8924                    if (!allowed) {
8925                        // If the caller doesn't have the GET_TASKS permission, then only
8926                        // allow them to see a small subset of tasks -- their own and home.
8927                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8928                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8929                            continue;
8930                        }
8931                    }
8932                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8933                        if (tr.stack != null && tr.stack.isHomeStack()) {
8934                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8935                                    "Skipping, home stack task: " + tr);
8936                            continue;
8937                        }
8938                    }
8939                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8940                        final ActivityStack stack = tr.stack;
8941                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8942                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8943                                    "Skipping, top task in docked stack: " + tr);
8944                            continue;
8945                        }
8946                    }
8947                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8948                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8949                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8950                                    "Skipping, pinned stack task: " + tr);
8951                            continue;
8952                        }
8953                    }
8954                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8955                        // Don't include auto remove tasks that are finished or finishing.
8956                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8957                                "Skipping, auto-remove without activity: " + tr);
8958                        continue;
8959                    }
8960                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8961                            && !tr.isAvailable) {
8962                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8963                                "Skipping, unavail real act: " + tr);
8964                        continue;
8965                    }
8966
8967                    if (!tr.mUserSetupComplete) {
8968                        // Don't include task launched while user is not done setting-up.
8969                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8970                                "Skipping, user setup not complete: " + tr);
8971                        continue;
8972                    }
8973
8974                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8975                    if (!detailed) {
8976                        rti.baseIntent.replaceExtras((Bundle)null);
8977                    }
8978
8979                    res.add(rti);
8980                    maxNum--;
8981                }
8982            }
8983            return res;
8984        }
8985    }
8986
8987    @Override
8988    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8989        synchronized (this) {
8990            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8991                    "getTaskThumbnail()");
8992            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8993                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8994            if (tr != null) {
8995                return tr.getTaskThumbnailLocked();
8996            }
8997        }
8998        return null;
8999    }
9000
9001    @Override
9002    public int addAppTask(IBinder activityToken, Intent intent,
9003            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9004        final int callingUid = Binder.getCallingUid();
9005        final long callingIdent = Binder.clearCallingIdentity();
9006
9007        try {
9008            synchronized (this) {
9009                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9010                if (r == null) {
9011                    throw new IllegalArgumentException("Activity does not exist; token="
9012                            + activityToken);
9013                }
9014                ComponentName comp = intent.getComponent();
9015                if (comp == null) {
9016                    throw new IllegalArgumentException("Intent " + intent
9017                            + " must specify explicit component");
9018                }
9019                if (thumbnail.getWidth() != mThumbnailWidth
9020                        || thumbnail.getHeight() != mThumbnailHeight) {
9021                    throw new IllegalArgumentException("Bad thumbnail size: got "
9022                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9023                            + mThumbnailWidth + "x" + mThumbnailHeight);
9024                }
9025                if (intent.getSelector() != null) {
9026                    intent.setSelector(null);
9027                }
9028                if (intent.getSourceBounds() != null) {
9029                    intent.setSourceBounds(null);
9030                }
9031                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9032                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9033                        // The caller has added this as an auto-remove task...  that makes no
9034                        // sense, so turn off auto-remove.
9035                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9036                    }
9037                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9038                    // Must be a new task.
9039                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9040                }
9041                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9042                    mLastAddedTaskActivity = null;
9043                }
9044                ActivityInfo ainfo = mLastAddedTaskActivity;
9045                if (ainfo == null) {
9046                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9047                            comp, 0, UserHandle.getUserId(callingUid));
9048                    if (ainfo.applicationInfo.uid != callingUid) {
9049                        throw new SecurityException(
9050                                "Can't add task for another application: target uid="
9051                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9052                    }
9053                }
9054
9055                // Use the full screen as the context for the task thumbnail
9056                final Point displaySize = new Point();
9057                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9058                r.task.stack.getDisplaySize(displaySize);
9059                thumbnailInfo.taskWidth = displaySize.x;
9060                thumbnailInfo.taskHeight = displaySize.y;
9061                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9062
9063                TaskRecord task = new TaskRecord(this,
9064                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9065                        ainfo, intent, description, thumbnailInfo);
9066
9067                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9068                if (trimIdx >= 0) {
9069                    // If this would have caused a trim, then we'll abort because that
9070                    // means it would be added at the end of the list but then just removed.
9071                    return INVALID_TASK_ID;
9072                }
9073
9074                final int N = mRecentTasks.size();
9075                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9076                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9077                    tr.removedFromRecents();
9078                }
9079
9080                task.inRecents = true;
9081                mRecentTasks.add(task);
9082                r.task.stack.addTask(task, false, "addAppTask");
9083
9084                task.setLastThumbnailLocked(thumbnail);
9085                task.freeLastThumbnail();
9086
9087                return task.taskId;
9088            }
9089        } finally {
9090            Binder.restoreCallingIdentity(callingIdent);
9091        }
9092    }
9093
9094    @Override
9095    public Point getAppTaskThumbnailSize() {
9096        synchronized (this) {
9097            return new Point(mThumbnailWidth,  mThumbnailHeight);
9098        }
9099    }
9100
9101    @Override
9102    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9103        synchronized (this) {
9104            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9105            if (r != null) {
9106                r.setTaskDescription(td);
9107                r.task.updateTaskDescription();
9108            }
9109        }
9110    }
9111
9112    @Override
9113    public void setTaskResizeable(int taskId, int resizeableMode) {
9114        synchronized (this) {
9115            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9116                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9117            if (task == null) {
9118                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9119                return;
9120            }
9121            if (task.mResizeMode != resizeableMode) {
9122                task.mResizeMode = resizeableMode;
9123                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9124                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9125                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9126            }
9127        }
9128    }
9129
9130    @Override
9131    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9132        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9133        long ident = Binder.clearCallingIdentity();
9134        try {
9135            synchronized (this) {
9136                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9137                if (task == null) {
9138                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9139                    return;
9140                }
9141                int stackId = task.stack.mStackId;
9142                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9143                // in crop windows resize mode or if the task size is affected by the docked stack
9144                // changing size. No need to update configuration.
9145                if (bounds != null && task.inCropWindowsResizeMode()
9146                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9147                    mWindowManager.scrollTask(task.taskId, bounds);
9148                    return;
9149                }
9150
9151                // Place the task in the right stack if it isn't there already based on
9152                // the requested bounds.
9153                // The stack transition logic is:
9154                // - a null bounds on a freeform task moves that task to fullscreen
9155                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9156                //   that task to freeform
9157                // - otherwise the task is not moved
9158                if (!StackId.isTaskResizeAllowed(stackId)) {
9159                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9160                }
9161                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9162                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9163                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9164                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9165                }
9166                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9167                if (stackId != task.stack.mStackId) {
9168                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9169                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9170                    preserveWindow = false;
9171                }
9172
9173                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9174                        false /* deferResume */);
9175            }
9176        } finally {
9177            Binder.restoreCallingIdentity(ident);
9178        }
9179    }
9180
9181    @Override
9182    public Rect getTaskBounds(int taskId) {
9183        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9184        long ident = Binder.clearCallingIdentity();
9185        Rect rect = new Rect();
9186        try {
9187            synchronized (this) {
9188                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9189                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9190                if (task == null) {
9191                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9192                    return rect;
9193                }
9194                if (task.stack != null) {
9195                    // Return the bounds from window manager since it will be adjusted for various
9196                    // things like the presense of a docked stack for tasks that aren't resizeable.
9197                    mWindowManager.getTaskBounds(task.taskId, rect);
9198                } else {
9199                    // Task isn't in window manager yet since it isn't associated with a stack.
9200                    // Return the persist value from activity manager
9201                    if (task.mBounds != null) {
9202                        rect.set(task.mBounds);
9203                    } else if (task.mLastNonFullscreenBounds != null) {
9204                        rect.set(task.mLastNonFullscreenBounds);
9205                    }
9206                }
9207            }
9208        } finally {
9209            Binder.restoreCallingIdentity(ident);
9210        }
9211        return rect;
9212    }
9213
9214    @Override
9215    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9216        if (userId != UserHandle.getCallingUserId()) {
9217            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9218                    "getTaskDescriptionIcon");
9219        }
9220        final File passedIconFile = new File(filePath);
9221        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9222                passedIconFile.getName());
9223        if (!legitIconFile.getPath().equals(filePath)
9224                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9225            throw new IllegalArgumentException("Bad file path: " + filePath
9226                    + " passed for userId " + userId);
9227        }
9228        return mRecentTasks.getTaskDescriptionIcon(filePath);
9229    }
9230
9231    @Override
9232    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9233            throws RemoteException {
9234        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9235                opts.getCustomInPlaceResId() == 0) {
9236            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9237                    "with valid animation");
9238        }
9239        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9240        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9241                opts.getCustomInPlaceResId());
9242        mWindowManager.executeAppTransition();
9243    }
9244
9245    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9246            boolean removeFromRecents) {
9247        if (removeFromRecents) {
9248            mRecentTasks.remove(tr);
9249            tr.removedFromRecents();
9250        }
9251        ComponentName component = tr.getBaseIntent().getComponent();
9252        if (component == null) {
9253            Slog.w(TAG, "No component for base intent of task: " + tr);
9254            return;
9255        }
9256
9257        // Find any running services associated with this app and stop if needed.
9258        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9259
9260        if (!killProcess) {
9261            return;
9262        }
9263
9264        // Determine if the process(es) for this task should be killed.
9265        final String pkg = component.getPackageName();
9266        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9267        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9268        for (int i = 0; i < pmap.size(); i++) {
9269
9270            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9271            for (int j = 0; j < uids.size(); j++) {
9272                ProcessRecord proc = uids.valueAt(j);
9273                if (proc.userId != tr.userId) {
9274                    // Don't kill process for a different user.
9275                    continue;
9276                }
9277                if (proc == mHomeProcess) {
9278                    // Don't kill the home process along with tasks from the same package.
9279                    continue;
9280                }
9281                if (!proc.pkgList.containsKey(pkg)) {
9282                    // Don't kill process that is not associated with this task.
9283                    continue;
9284                }
9285
9286                for (int k = 0; k < proc.activities.size(); k++) {
9287                    TaskRecord otherTask = proc.activities.get(k).task;
9288                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9289                        // Don't kill process(es) that has an activity in a different task that is
9290                        // also in recents.
9291                        return;
9292                    }
9293                }
9294
9295                if (proc.foregroundServices) {
9296                    // Don't kill process(es) with foreground service.
9297                    return;
9298                }
9299
9300                // Add process to kill list.
9301                procsToKill.add(proc);
9302            }
9303        }
9304
9305        // Kill the running processes.
9306        for (int i = 0; i < procsToKill.size(); i++) {
9307            ProcessRecord pr = procsToKill.get(i);
9308            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9309                    && pr.curReceiver == null) {
9310                pr.kill("remove task", true);
9311            } else {
9312                // We delay killing processes that are not in the background or running a receiver.
9313                pr.waitingToKill = "remove task";
9314            }
9315        }
9316    }
9317
9318    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9319        // Remove all tasks with activities in the specified package from the list of recent tasks
9320        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9321            TaskRecord tr = mRecentTasks.get(i);
9322            if (tr.userId != userId) continue;
9323
9324            ComponentName cn = tr.intent.getComponent();
9325            if (cn != null && cn.getPackageName().equals(packageName)) {
9326                // If the package name matches, remove the task.
9327                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9328            }
9329        }
9330    }
9331
9332    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9333            int userId) {
9334
9335        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9336            TaskRecord tr = mRecentTasks.get(i);
9337            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9338                continue;
9339            }
9340
9341            ComponentName cn = tr.intent.getComponent();
9342            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9343                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9344            if (sameComponent) {
9345                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9346            }
9347        }
9348    }
9349
9350    /**
9351     * Removes the task with the specified task id.
9352     *
9353     * @param taskId Identifier of the task to be removed.
9354     * @param killProcess Kill any process associated with the task if possible.
9355     * @param removeFromRecents Whether to also remove the task from recents.
9356     * @return Returns true if the given task was found and removed.
9357     */
9358    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9359            boolean removeFromRecents) {
9360        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9361                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9362        if (tr != null) {
9363            tr.removeTaskActivitiesLocked();
9364            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9365            if (tr.isPersistable) {
9366                notifyTaskPersisterLocked(null, true);
9367            }
9368            return true;
9369        }
9370        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9371        return false;
9372    }
9373
9374    @Override
9375    public void removeStack(int stackId) {
9376        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9377        if (stackId == HOME_STACK_ID) {
9378            throw new IllegalArgumentException("Removing home stack is not allowed.");
9379        }
9380
9381        synchronized (this) {
9382            final long ident = Binder.clearCallingIdentity();
9383            try {
9384                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9385                if (stack == null) {
9386                    return;
9387                }
9388                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9389                for (int i = tasks.size() - 1; i >= 0; i--) {
9390                    removeTaskByIdLocked(
9391                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9392                }
9393            } finally {
9394                Binder.restoreCallingIdentity(ident);
9395            }
9396        }
9397    }
9398
9399    @Override
9400    public boolean removeTask(int taskId) {
9401        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9402        synchronized (this) {
9403            final long ident = Binder.clearCallingIdentity();
9404            try {
9405                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9406            } finally {
9407                Binder.restoreCallingIdentity(ident);
9408            }
9409        }
9410    }
9411
9412    /**
9413     * TODO: Add mController hook
9414     */
9415    @Override
9416    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9417        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9418
9419        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9420        synchronized(this) {
9421            moveTaskToFrontLocked(taskId, flags, bOptions);
9422        }
9423    }
9424
9425    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9426        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9427
9428        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9429                Binder.getCallingUid(), -1, -1, "Task to front")) {
9430            ActivityOptions.abort(options);
9431            return;
9432        }
9433        final long origId = Binder.clearCallingIdentity();
9434        try {
9435            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9436            if (task == null) {
9437                Slog.d(TAG, "Could not find task for id: "+ taskId);
9438                return;
9439            }
9440            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9441                mStackSupervisor.showLockTaskToast();
9442                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9443                return;
9444            }
9445            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9446            if (prev != null && prev.isRecentsActivity()) {
9447                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9448            }
9449            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9450                    false /* forceNonResizable */);
9451        } finally {
9452            Binder.restoreCallingIdentity(origId);
9453        }
9454        ActivityOptions.abort(options);
9455    }
9456
9457    /**
9458     * Moves an activity, and all of the other activities within the same task, to the bottom
9459     * of the history stack.  The activity's order within the task is unchanged.
9460     *
9461     * @param token A reference to the activity we wish to move
9462     * @param nonRoot If false then this only works if the activity is the root
9463     *                of a task; if true it will work for any activity in a task.
9464     * @return Returns true if the move completed, false if not.
9465     */
9466    @Override
9467    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9468        enforceNotIsolatedCaller("moveActivityTaskToBack");
9469        synchronized(this) {
9470            final long origId = Binder.clearCallingIdentity();
9471            try {
9472                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9473                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9474                if (task != null) {
9475                    if (mStackSupervisor.isLockedTask(task)) {
9476                        mStackSupervisor.showLockTaskToast();
9477                        return false;
9478                    }
9479                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9480                }
9481            } finally {
9482                Binder.restoreCallingIdentity(origId);
9483            }
9484        }
9485        return false;
9486    }
9487
9488    @Override
9489    public void moveTaskBackwards(int task) {
9490        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9491                "moveTaskBackwards()");
9492
9493        synchronized(this) {
9494            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9495                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9496                return;
9497            }
9498            final long origId = Binder.clearCallingIdentity();
9499            moveTaskBackwardsLocked(task);
9500            Binder.restoreCallingIdentity(origId);
9501        }
9502    }
9503
9504    private final void moveTaskBackwardsLocked(int task) {
9505        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9506    }
9507
9508    @Override
9509    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9510            IActivityContainerCallback callback) throws RemoteException {
9511        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9512        synchronized (this) {
9513            if (parentActivityToken == null) {
9514                throw new IllegalArgumentException("parent token must not be null");
9515            }
9516            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9517            if (r == null) {
9518                return null;
9519            }
9520            if (callback == null) {
9521                throw new IllegalArgumentException("callback must not be null");
9522            }
9523            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9524        }
9525    }
9526
9527    @Override
9528    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9529        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9530        synchronized (this) {
9531            mStackSupervisor.deleteActivityContainer(container);
9532        }
9533    }
9534
9535    @Override
9536    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9537        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9538        synchronized (this) {
9539            final int stackId = mStackSupervisor.getNextStackId();
9540            final ActivityStack stack =
9541                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9542            if (stack == null) {
9543                return null;
9544            }
9545            return stack.mActivityContainer;
9546        }
9547    }
9548
9549    @Override
9550    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9551        synchronized (this) {
9552            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9553            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9554                return stack.mActivityContainer.getDisplayId();
9555            }
9556            return Display.DEFAULT_DISPLAY;
9557        }
9558    }
9559
9560    @Override
9561    public int getActivityStackId(IBinder token) throws RemoteException {
9562        synchronized (this) {
9563            ActivityStack stack = ActivityRecord.getStackLocked(token);
9564            if (stack == null) {
9565                return INVALID_STACK_ID;
9566            }
9567            return stack.mStackId;
9568        }
9569    }
9570
9571    @Override
9572    public void exitFreeformMode(IBinder token) throws RemoteException {
9573        synchronized (this) {
9574            long ident = Binder.clearCallingIdentity();
9575            try {
9576                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9577                if (r == null) {
9578                    throw new IllegalArgumentException(
9579                            "exitFreeformMode: No activity record matching token=" + token);
9580                }
9581                final ActivityStack stack = r.getStackLocked(token);
9582                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9583                    throw new IllegalStateException(
9584                            "exitFreeformMode: You can only go fullscreen from freeform.");
9585                }
9586                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9587                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9588                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9589            } finally {
9590                Binder.restoreCallingIdentity(ident);
9591            }
9592        }
9593    }
9594
9595    @Override
9596    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9597        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9598        if (stackId == HOME_STACK_ID) {
9599            throw new IllegalArgumentException(
9600                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9601        }
9602        synchronized (this) {
9603            long ident = Binder.clearCallingIdentity();
9604            try {
9605                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9606                        + " to stackId=" + stackId + " toTop=" + toTop);
9607                if (stackId == DOCKED_STACK_ID) {
9608                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9609                            null /* initialBounds */);
9610                }
9611                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9612                        "moveTaskToStack", ANIMATE);
9613            } finally {
9614                Binder.restoreCallingIdentity(ident);
9615            }
9616        }
9617    }
9618
9619    @Override
9620    public void swapDockedAndFullscreenStack() throws RemoteException {
9621        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9622        synchronized (this) {
9623            long ident = Binder.clearCallingIdentity();
9624            try {
9625                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9626                        FULLSCREEN_WORKSPACE_STACK_ID);
9627                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9628                        : null;
9629                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9630                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9631                        : null;
9632                if (topTask == null || tasks == null || tasks.size() == 0) {
9633                    Slog.w(TAG,
9634                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9635                    return;
9636                }
9637
9638                // TODO: App transition
9639                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9640
9641                // Defer the resume so resume/pausing while moving stacks is dangerous.
9642                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9643                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9644                        ANIMATE, true /* deferResume */);
9645                final int size = tasks.size();
9646                for (int i = 0; i < size; i++) {
9647                    final int id = tasks.get(i).taskId;
9648                    if (id == topTask.taskId) {
9649                        continue;
9650                    }
9651                    mStackSupervisor.moveTaskToStackLocked(id,
9652                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9653                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9654                }
9655
9656                // Because we deferred the resume, to avoid conflicts with stack switches while
9657                // resuming, we need to do it after all the tasks are moved.
9658                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9659                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9660
9661                mWindowManager.executeAppTransition();
9662            } finally {
9663                Binder.restoreCallingIdentity(ident);
9664            }
9665        }
9666    }
9667
9668    /**
9669     * Moves the input task to the docked stack.
9670     *
9671     * @param taskId Id of task to move.
9672     * @param createMode The mode the docked stack should be created in if it doesn't exist
9673     *                   already. See
9674     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9675     *                   and
9676     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9677     * @param toTop If the task and stack should be moved to the top.
9678     * @param animate Whether we should play an animation for the moving the task
9679     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9680     *                      docked stack. Pass {@code null} to use default bounds.
9681     */
9682    @Override
9683    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9684            Rect initialBounds) {
9685        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9686        synchronized (this) {
9687            long ident = Binder.clearCallingIdentity();
9688            try {
9689                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9690                        + " to createMode=" + createMode + " toTop=" + toTop);
9691                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9692                return mStackSupervisor.moveTaskToStackLocked(
9693                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9694                        "moveTaskToDockedStack", animate);
9695            } finally {
9696                Binder.restoreCallingIdentity(ident);
9697            }
9698        }
9699    }
9700
9701    /**
9702     * Moves the top activity in the input stackId to the pinned stack.
9703     *
9704     * @param stackId Id of stack to move the top activity to pinned stack.
9705     * @param bounds Bounds to use for pinned stack.
9706     *
9707     * @return True if the top activity of the input stack was successfully moved to the pinned
9708     *          stack.
9709     */
9710    @Override
9711    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9712        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9713        synchronized (this) {
9714            if (!mSupportsPictureInPicture) {
9715                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9716                        + "Device doesn't support picture-in-pciture mode");
9717            }
9718
9719            long ident = Binder.clearCallingIdentity();
9720            try {
9721                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9722            } finally {
9723                Binder.restoreCallingIdentity(ident);
9724            }
9725        }
9726    }
9727
9728    @Override
9729    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9730            boolean preserveWindows, boolean animate, int animationDuration) {
9731        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9732        long ident = Binder.clearCallingIdentity();
9733        try {
9734            synchronized (this) {
9735                if (animate) {
9736                    if (stackId == PINNED_STACK_ID) {
9737                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9738                    } else {
9739                        throw new IllegalArgumentException("Stack: " + stackId
9740                                + " doesn't support animated resize.");
9741                    }
9742                } else {
9743                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9744                            null /* tempTaskInsetBounds */, preserveWindows,
9745                            allowResizeInDockedMode, !DEFER_RESUME);
9746                }
9747            }
9748        } finally {
9749            Binder.restoreCallingIdentity(ident);
9750        }
9751    }
9752
9753    @Override
9754    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9755            Rect tempDockedTaskInsetBounds,
9756            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9757        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9758                "resizeDockedStack()");
9759        long ident = Binder.clearCallingIdentity();
9760        try {
9761            synchronized (this) {
9762                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9763                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9764                        PRESERVE_WINDOWS);
9765            }
9766        } finally {
9767            Binder.restoreCallingIdentity(ident);
9768        }
9769    }
9770
9771    @Override
9772    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9773        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9774                "resizePinnedStack()");
9775        final long ident = Binder.clearCallingIdentity();
9776        try {
9777            synchronized (this) {
9778                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9779            }
9780        } finally {
9781            Binder.restoreCallingIdentity(ident);
9782        }
9783    }
9784
9785    @Override
9786    public void positionTaskInStack(int taskId, int stackId, int position) {
9787        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9788        if (stackId == HOME_STACK_ID) {
9789            throw new IllegalArgumentException(
9790                    "positionTaskInStack: Attempt to change the position of task "
9791                    + taskId + " in/to home stack");
9792        }
9793        synchronized (this) {
9794            long ident = Binder.clearCallingIdentity();
9795            try {
9796                if (DEBUG_STACK) Slog.d(TAG_STACK,
9797                        "positionTaskInStack: positioning task=" + taskId
9798                        + " in stackId=" + stackId + " at position=" + position);
9799                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9800            } finally {
9801                Binder.restoreCallingIdentity(ident);
9802            }
9803        }
9804    }
9805
9806    @Override
9807    public List<StackInfo> getAllStackInfos() {
9808        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9809        long ident = Binder.clearCallingIdentity();
9810        try {
9811            synchronized (this) {
9812                return mStackSupervisor.getAllStackInfosLocked();
9813            }
9814        } finally {
9815            Binder.restoreCallingIdentity(ident);
9816        }
9817    }
9818
9819    @Override
9820    public StackInfo getStackInfo(int stackId) {
9821        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9822        long ident = Binder.clearCallingIdentity();
9823        try {
9824            synchronized (this) {
9825                return mStackSupervisor.getStackInfoLocked(stackId);
9826            }
9827        } finally {
9828            Binder.restoreCallingIdentity(ident);
9829        }
9830    }
9831
9832    @Override
9833    public boolean isInHomeStack(int taskId) {
9834        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9835        long ident = Binder.clearCallingIdentity();
9836        try {
9837            synchronized (this) {
9838                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9839                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9840                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9841            }
9842        } finally {
9843            Binder.restoreCallingIdentity(ident);
9844        }
9845    }
9846
9847    @Override
9848    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9849        synchronized(this) {
9850            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9851        }
9852    }
9853
9854    @Override
9855    public void updateDeviceOwner(String packageName) {
9856        final int callingUid = Binder.getCallingUid();
9857        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9858            throw new SecurityException("updateDeviceOwner called from non-system process");
9859        }
9860        synchronized (this) {
9861            mDeviceOwnerName = packageName;
9862        }
9863    }
9864
9865    @Override
9866    public void updateLockTaskPackages(int userId, String[] packages) {
9867        final int callingUid = Binder.getCallingUid();
9868        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9869            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9870                    "updateLockTaskPackages()");
9871        }
9872        synchronized (this) {
9873            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9874                    Arrays.toString(packages));
9875            mLockTaskPackages.put(userId, packages);
9876            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9877        }
9878    }
9879
9880
9881    void startLockTaskModeLocked(TaskRecord task) {
9882        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9883        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9884            return;
9885        }
9886
9887        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9888        // is initiated by system after the pinning request was shown and locked mode is initiated
9889        // by an authorized app directly
9890        final int callingUid = Binder.getCallingUid();
9891        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9892        long ident = Binder.clearCallingIdentity();
9893        try {
9894            if (!isSystemInitiated) {
9895                task.mLockTaskUid = callingUid;
9896                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9897                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9898                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9899                    StatusBarManagerInternal statusBarManager =
9900                            LocalServices.getService(StatusBarManagerInternal.class);
9901                    if (statusBarManager != null) {
9902                        statusBarManager.showScreenPinningRequest(task.taskId);
9903                    }
9904                    return;
9905                }
9906
9907                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9908                if (stack == null || task != stack.topTask()) {
9909                    throw new IllegalArgumentException("Invalid task, not in foreground");
9910                }
9911            }
9912            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9913                    "Locking fully");
9914            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9915                    ActivityManager.LOCK_TASK_MODE_PINNED :
9916                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9917                    "startLockTask", true);
9918        } finally {
9919            Binder.restoreCallingIdentity(ident);
9920        }
9921    }
9922
9923    @Override
9924    public void startLockTaskMode(int taskId) {
9925        synchronized (this) {
9926            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9927            if (task != null) {
9928                startLockTaskModeLocked(task);
9929            }
9930        }
9931    }
9932
9933    @Override
9934    public void startLockTaskMode(IBinder token) {
9935        synchronized (this) {
9936            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9937            if (r == null) {
9938                return;
9939            }
9940            final TaskRecord task = r.task;
9941            if (task != null) {
9942                startLockTaskModeLocked(task);
9943            }
9944        }
9945    }
9946
9947    @Override
9948    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9949        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9950        // This makes inner call to look as if it was initiated by system.
9951        long ident = Binder.clearCallingIdentity();
9952        try {
9953            synchronized (this) {
9954                startLockTaskMode(taskId);
9955            }
9956        } finally {
9957            Binder.restoreCallingIdentity(ident);
9958        }
9959    }
9960
9961    @Override
9962    public void stopLockTaskMode() {
9963        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9964        if (lockTask == null) {
9965            // Our work here is done.
9966            return;
9967        }
9968
9969        final int callingUid = Binder.getCallingUid();
9970        final int lockTaskUid = lockTask.mLockTaskUid;
9971        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9972        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9973            // Done.
9974            return;
9975        } else {
9976            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9977            // It is possible lockTaskMode was started by the system process because
9978            // android:lockTaskMode is set to a locking value in the application manifest
9979            // instead of the app calling startLockTaskMode. In this case
9980            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
9981            // {@link TaskRecord.effectiveUid} instead. Also caller with
9982            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
9983            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
9984                    && callingUid != lockTaskUid
9985                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
9986                throw new SecurityException("Invalid uid, expected " + lockTaskUid
9987                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9988            }
9989        }
9990        long ident = Binder.clearCallingIdentity();
9991        try {
9992            Log.d(TAG, "stopLockTaskMode");
9993            // Stop lock task
9994            synchronized (this) {
9995                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9996                        "stopLockTask", true);
9997            }
9998        } finally {
9999            Binder.restoreCallingIdentity(ident);
10000        }
10001    }
10002
10003    /**
10004     * This API should be called by SystemUI only when user perform certain action to dismiss
10005     * lock task mode. We should only dismiss pinned lock task mode in this case.
10006     */
10007    @Override
10008    public void stopSystemLockTaskMode() throws RemoteException {
10009        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10010            stopLockTaskMode();
10011        } else {
10012            mStackSupervisor.showLockTaskToast();
10013        }
10014    }
10015
10016    @Override
10017    public boolean isInLockTaskMode() {
10018        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10019    }
10020
10021    @Override
10022    public int getLockTaskModeState() {
10023        synchronized (this) {
10024            return mStackSupervisor.getLockTaskModeState();
10025        }
10026    }
10027
10028    @Override
10029    public void showLockTaskEscapeMessage(IBinder token) {
10030        synchronized (this) {
10031            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10032            if (r == null) {
10033                return;
10034            }
10035            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10036        }
10037    }
10038
10039    // =========================================================
10040    // CONTENT PROVIDERS
10041    // =========================================================
10042
10043    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10044        List<ProviderInfo> providers = null;
10045        try {
10046            providers = AppGlobals.getPackageManager()
10047                    .queryContentProviders(app.processName, app.uid,
10048                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10049                                    | MATCH_DEBUG_TRIAGED_MISSING)
10050                    .getList();
10051        } catch (RemoteException ex) {
10052        }
10053        if (DEBUG_MU) Slog.v(TAG_MU,
10054                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10055        int userId = app.userId;
10056        if (providers != null) {
10057            int N = providers.size();
10058            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10059            for (int i=0; i<N; i++) {
10060                ProviderInfo cpi =
10061                    (ProviderInfo)providers.get(i);
10062                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10063                        cpi.name, cpi.flags);
10064                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10065                    // This is a singleton provider, but a user besides the
10066                    // default user is asking to initialize a process it runs
10067                    // in...  well, no, it doesn't actually run in this process,
10068                    // it runs in the process of the default user.  Get rid of it.
10069                    providers.remove(i);
10070                    N--;
10071                    i--;
10072                    continue;
10073                }
10074
10075                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10076                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10077                if (cpr == null) {
10078                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10079                    mProviderMap.putProviderByClass(comp, cpr);
10080                }
10081                if (DEBUG_MU) Slog.v(TAG_MU,
10082                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10083                app.pubProviders.put(cpi.name, cpr);
10084                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10085                    // Don't add this if it is a platform component that is marked
10086                    // to run in multiple processes, because this is actually
10087                    // part of the framework so doesn't make sense to track as a
10088                    // separate apk in the process.
10089                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10090                            mProcessStats);
10091                }
10092                notifyPackageUse(cpi.applicationInfo.packageName);
10093            }
10094        }
10095        return providers;
10096    }
10097
10098    /**
10099     * Check if {@link ProcessRecord} has a possible chance at accessing the
10100     * given {@link ProviderInfo}. Final permission checking is always done
10101     * in {@link ContentProvider}.
10102     */
10103    private final String checkContentProviderPermissionLocked(
10104            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10105        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10106        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10107        boolean checkedGrants = false;
10108        if (checkUser) {
10109            // Looking for cross-user grants before enforcing the typical cross-users permissions
10110            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10111            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10112                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10113                    return null;
10114                }
10115                checkedGrants = true;
10116            }
10117            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10118                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10119            if (userId != tmpTargetUserId) {
10120                // When we actually went to determine the final targer user ID, this ended
10121                // up different than our initial check for the authority.  This is because
10122                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10123                // SELF.  So we need to re-check the grants again.
10124                checkedGrants = false;
10125            }
10126        }
10127        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10128                cpi.applicationInfo.uid, cpi.exported)
10129                == PackageManager.PERMISSION_GRANTED) {
10130            return null;
10131        }
10132        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10133                cpi.applicationInfo.uid, cpi.exported)
10134                == PackageManager.PERMISSION_GRANTED) {
10135            return null;
10136        }
10137
10138        PathPermission[] pps = cpi.pathPermissions;
10139        if (pps != null) {
10140            int i = pps.length;
10141            while (i > 0) {
10142                i--;
10143                PathPermission pp = pps[i];
10144                String pprperm = pp.getReadPermission();
10145                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10146                        cpi.applicationInfo.uid, cpi.exported)
10147                        == PackageManager.PERMISSION_GRANTED) {
10148                    return null;
10149                }
10150                String ppwperm = pp.getWritePermission();
10151                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10152                        cpi.applicationInfo.uid, cpi.exported)
10153                        == PackageManager.PERMISSION_GRANTED) {
10154                    return null;
10155                }
10156            }
10157        }
10158        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10159            return null;
10160        }
10161
10162        String msg;
10163        if (!cpi.exported) {
10164            msg = "Permission Denial: opening provider " + cpi.name
10165                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10166                    + ", uid=" + callingUid + ") that is not exported from uid "
10167                    + cpi.applicationInfo.uid;
10168        } else {
10169            msg = "Permission Denial: opening provider " + cpi.name
10170                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10171                    + ", uid=" + callingUid + ") requires "
10172                    + cpi.readPermission + " or " + cpi.writePermission;
10173        }
10174        Slog.w(TAG, msg);
10175        return msg;
10176    }
10177
10178    /**
10179     * Returns if the ContentProvider has granted a uri to callingUid
10180     */
10181    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10182        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10183        if (perms != null) {
10184            for (int i=perms.size()-1; i>=0; i--) {
10185                GrantUri grantUri = perms.keyAt(i);
10186                if (grantUri.sourceUserId == userId || !checkUser) {
10187                    if (matchesProvider(grantUri.uri, cpi)) {
10188                        return true;
10189                    }
10190                }
10191            }
10192        }
10193        return false;
10194    }
10195
10196    /**
10197     * Returns true if the uri authority is one of the authorities specified in the provider.
10198     */
10199    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10200        String uriAuth = uri.getAuthority();
10201        String cpiAuth = cpi.authority;
10202        if (cpiAuth.indexOf(';') == -1) {
10203            return cpiAuth.equals(uriAuth);
10204        }
10205        String[] cpiAuths = cpiAuth.split(";");
10206        int length = cpiAuths.length;
10207        for (int i = 0; i < length; i++) {
10208            if (cpiAuths[i].equals(uriAuth)) return true;
10209        }
10210        return false;
10211    }
10212
10213    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10214            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10215        if (r != null) {
10216            for (int i=0; i<r.conProviders.size(); i++) {
10217                ContentProviderConnection conn = r.conProviders.get(i);
10218                if (conn.provider == cpr) {
10219                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10220                            "Adding provider requested by "
10221                            + r.processName + " from process "
10222                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10223                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10224                    if (stable) {
10225                        conn.stableCount++;
10226                        conn.numStableIncs++;
10227                    } else {
10228                        conn.unstableCount++;
10229                        conn.numUnstableIncs++;
10230                    }
10231                    return conn;
10232                }
10233            }
10234            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10235            if (stable) {
10236                conn.stableCount = 1;
10237                conn.numStableIncs = 1;
10238            } else {
10239                conn.unstableCount = 1;
10240                conn.numUnstableIncs = 1;
10241            }
10242            cpr.connections.add(conn);
10243            r.conProviders.add(conn);
10244            startAssociationLocked(r.uid, r.processName, r.curProcState,
10245                    cpr.uid, cpr.name, cpr.info.processName);
10246            return conn;
10247        }
10248        cpr.addExternalProcessHandleLocked(externalProcessToken);
10249        return null;
10250    }
10251
10252    boolean decProviderCountLocked(ContentProviderConnection conn,
10253            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10254        if (conn != null) {
10255            cpr = conn.provider;
10256            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10257                    "Removing provider requested by "
10258                    + conn.client.processName + " from process "
10259                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10260                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10261            if (stable) {
10262                conn.stableCount--;
10263            } else {
10264                conn.unstableCount--;
10265            }
10266            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10267                cpr.connections.remove(conn);
10268                conn.client.conProviders.remove(conn);
10269                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10270                    // The client is more important than last activity -- note the time this
10271                    // is happening, so we keep the old provider process around a bit as last
10272                    // activity to avoid thrashing it.
10273                    if (cpr.proc != null) {
10274                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10275                    }
10276                }
10277                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10278                return true;
10279            }
10280            return false;
10281        }
10282        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10283        return false;
10284    }
10285
10286    private void checkTime(long startTime, String where) {
10287        long now = SystemClock.elapsedRealtime();
10288        if ((now-startTime) > 1000) {
10289            // If we are taking more than a second, log about it.
10290            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10291        }
10292    }
10293
10294    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10295            String name, IBinder token, boolean stable, int userId) {
10296        ContentProviderRecord cpr;
10297        ContentProviderConnection conn = null;
10298        ProviderInfo cpi = null;
10299
10300        synchronized(this) {
10301            long startTime = SystemClock.elapsedRealtime();
10302
10303            ProcessRecord r = null;
10304            if (caller != null) {
10305                r = getRecordForAppLocked(caller);
10306                if (r == null) {
10307                    throw new SecurityException(
10308                            "Unable to find app for caller " + caller
10309                          + " (pid=" + Binder.getCallingPid()
10310                          + ") when getting content provider " + name);
10311                }
10312            }
10313
10314            boolean checkCrossUser = true;
10315
10316            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10317
10318            // First check if this content provider has been published...
10319            cpr = mProviderMap.getProviderByName(name, userId);
10320            // If that didn't work, check if it exists for user 0 and then
10321            // verify that it's a singleton provider before using it.
10322            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10323                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10324                if (cpr != null) {
10325                    cpi = cpr.info;
10326                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10327                            cpi.name, cpi.flags)
10328                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10329                        userId = UserHandle.USER_SYSTEM;
10330                        checkCrossUser = false;
10331                    } else {
10332                        cpr = null;
10333                        cpi = null;
10334                    }
10335                }
10336            }
10337
10338            boolean providerRunning = cpr != null;
10339            if (providerRunning) {
10340                cpi = cpr.info;
10341                String msg;
10342                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10343                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10344                        != null) {
10345                    throw new SecurityException(msg);
10346                }
10347                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10348
10349                if (r != null && cpr.canRunHere(r)) {
10350                    // This provider has been published or is in the process
10351                    // of being published...  but it is also allowed to run
10352                    // in the caller's process, so don't make a connection
10353                    // and just let the caller instantiate its own instance.
10354                    ContentProviderHolder holder = cpr.newHolder(null);
10355                    // don't give caller the provider object, it needs
10356                    // to make its own.
10357                    holder.provider = null;
10358                    return holder;
10359                }
10360
10361                final long origId = Binder.clearCallingIdentity();
10362
10363                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10364
10365                // In this case the provider instance already exists, so we can
10366                // return it right away.
10367                conn = incProviderCountLocked(r, cpr, token, stable);
10368                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10369                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10370                        // If this is a perceptible app accessing the provider,
10371                        // make sure to count it as being accessed and thus
10372                        // back up on the LRU list.  This is good because
10373                        // content providers are often expensive to start.
10374                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10375                        updateLruProcessLocked(cpr.proc, false, null);
10376                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10377                    }
10378                }
10379
10380                if (cpr.proc != null) {
10381                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10382                    boolean success = updateOomAdjLocked(cpr.proc);
10383                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10384                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10385                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10386                    // NOTE: there is still a race here where a signal could be
10387                    // pending on the process even though we managed to update its
10388                    // adj level.  Not sure what to do about this, but at least
10389                    // the race is now smaller.
10390                    if (!success) {
10391                        // Uh oh...  it looks like the provider's process
10392                        // has been killed on us.  We need to wait for a new
10393                        // process to be started, and make sure its death
10394                        // doesn't kill our process.
10395                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10396                                + " is crashing; detaching " + r);
10397                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10398                        checkTime(startTime, "getContentProviderImpl: before appDied");
10399                        appDiedLocked(cpr.proc);
10400                        checkTime(startTime, "getContentProviderImpl: after appDied");
10401                        if (!lastRef) {
10402                            // This wasn't the last ref our process had on
10403                            // the provider...  we have now been killed, bail.
10404                            return null;
10405                        }
10406                        providerRunning = false;
10407                        conn = null;
10408                    }
10409                }
10410
10411                Binder.restoreCallingIdentity(origId);
10412            }
10413
10414            if (!providerRunning) {
10415                try {
10416                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10417                    cpi = AppGlobals.getPackageManager().
10418                        resolveContentProvider(name,
10419                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10420                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10421                } catch (RemoteException ex) {
10422                }
10423                if (cpi == null) {
10424                    return null;
10425                }
10426                // If the provider is a singleton AND
10427                // (it's a call within the same user || the provider is a
10428                // privileged app)
10429                // Then allow connecting to the singleton provider
10430                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10431                        cpi.name, cpi.flags)
10432                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10433                if (singleton) {
10434                    userId = UserHandle.USER_SYSTEM;
10435                }
10436                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10437                checkTime(startTime, "getContentProviderImpl: got app info for user");
10438
10439                String msg;
10440                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10441                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10442                        != null) {
10443                    throw new SecurityException(msg);
10444                }
10445                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10446
10447                if (!mProcessesReady
10448                        && !cpi.processName.equals("system")) {
10449                    // If this content provider does not run in the system
10450                    // process, and the system is not yet ready to run other
10451                    // processes, then fail fast instead of hanging.
10452                    throw new IllegalArgumentException(
10453                            "Attempt to launch content provider before system ready");
10454                }
10455
10456                // Make sure that the user who owns this provider is running.  If not,
10457                // we don't want to allow it to run.
10458                if (!mUserController.isUserRunningLocked(userId, 0)) {
10459                    Slog.w(TAG, "Unable to launch app "
10460                            + cpi.applicationInfo.packageName + "/"
10461                            + cpi.applicationInfo.uid + " for provider "
10462                            + name + ": user " + userId + " is stopped");
10463                    return null;
10464                }
10465
10466                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10467                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10468                cpr = mProviderMap.getProviderByClass(comp, userId);
10469                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10470                final boolean firstClass = cpr == null;
10471                if (firstClass) {
10472                    final long ident = Binder.clearCallingIdentity();
10473
10474                    // If permissions need a review before any of the app components can run,
10475                    // we return no provider and launch a review activity if the calling app
10476                    // is in the foreground.
10477                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10478                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10479                            return null;
10480                        }
10481                    }
10482
10483                    try {
10484                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10485                        ApplicationInfo ai =
10486                            AppGlobals.getPackageManager().
10487                                getApplicationInfo(
10488                                        cpi.applicationInfo.packageName,
10489                                        STOCK_PM_FLAGS, userId);
10490                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10491                        if (ai == null) {
10492                            Slog.w(TAG, "No package info for content provider "
10493                                    + cpi.name);
10494                            return null;
10495                        }
10496                        ai = getAppInfoForUser(ai, userId);
10497                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10498                    } catch (RemoteException ex) {
10499                        // pm is in same process, this will never happen.
10500                    } finally {
10501                        Binder.restoreCallingIdentity(ident);
10502                    }
10503                }
10504
10505                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10506
10507                if (r != null && cpr.canRunHere(r)) {
10508                    // If this is a multiprocess provider, then just return its
10509                    // info and allow the caller to instantiate it.  Only do
10510                    // this if the provider is the same user as the caller's
10511                    // process, or can run as root (so can be in any process).
10512                    return cpr.newHolder(null);
10513                }
10514
10515                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10516                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10517                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10518
10519                // This is single process, and our app is now connecting to it.
10520                // See if we are already in the process of launching this
10521                // provider.
10522                final int N = mLaunchingProviders.size();
10523                int i;
10524                for (i = 0; i < N; i++) {
10525                    if (mLaunchingProviders.get(i) == cpr) {
10526                        break;
10527                    }
10528                }
10529
10530                // If the provider is not already being launched, then get it
10531                // started.
10532                if (i >= N) {
10533                    final long origId = Binder.clearCallingIdentity();
10534
10535                    try {
10536                        // Content provider is now in use, its package can't be stopped.
10537                        try {
10538                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10539                            AppGlobals.getPackageManager().setPackageStoppedState(
10540                                    cpr.appInfo.packageName, false, userId);
10541                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10542                        } catch (RemoteException e) {
10543                        } catch (IllegalArgumentException e) {
10544                            Slog.w(TAG, "Failed trying to unstop package "
10545                                    + cpr.appInfo.packageName + ": " + e);
10546                        }
10547
10548                        // Use existing process if already started
10549                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10550                        ProcessRecord proc = getProcessRecordLocked(
10551                                cpi.processName, cpr.appInfo.uid, false);
10552                        if (proc != null && proc.thread != null) {
10553                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10554                                    "Installing in existing process " + proc);
10555                            if (!proc.pubProviders.containsKey(cpi.name)) {
10556                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10557                                proc.pubProviders.put(cpi.name, cpr);
10558                                try {
10559                                    proc.thread.scheduleInstallProvider(cpi);
10560                                } catch (RemoteException e) {
10561                                }
10562                            }
10563                        } else {
10564                            checkTime(startTime, "getContentProviderImpl: before start process");
10565                            proc = startProcessLocked(cpi.processName,
10566                                    cpr.appInfo, false, 0, "content provider",
10567                                    new ComponentName(cpi.applicationInfo.packageName,
10568                                            cpi.name), false, false, false);
10569                            checkTime(startTime, "getContentProviderImpl: after start process");
10570                            if (proc == null) {
10571                                Slog.w(TAG, "Unable to launch app "
10572                                        + cpi.applicationInfo.packageName + "/"
10573                                        + cpi.applicationInfo.uid + " for provider "
10574                                        + name + ": process is bad");
10575                                return null;
10576                            }
10577                        }
10578                        cpr.launchingApp = proc;
10579                        mLaunchingProviders.add(cpr);
10580                    } finally {
10581                        Binder.restoreCallingIdentity(origId);
10582                    }
10583                }
10584
10585                checkTime(startTime, "getContentProviderImpl: updating data structures");
10586
10587                // Make sure the provider is published (the same provider class
10588                // may be published under multiple names).
10589                if (firstClass) {
10590                    mProviderMap.putProviderByClass(comp, cpr);
10591                }
10592
10593                mProviderMap.putProviderByName(name, cpr);
10594                conn = incProviderCountLocked(r, cpr, token, stable);
10595                if (conn != null) {
10596                    conn.waiting = true;
10597                }
10598            }
10599            checkTime(startTime, "getContentProviderImpl: done!");
10600        }
10601
10602        // Wait for the provider to be published...
10603        synchronized (cpr) {
10604            while (cpr.provider == null) {
10605                if (cpr.launchingApp == null) {
10606                    Slog.w(TAG, "Unable to launch app "
10607                            + cpi.applicationInfo.packageName + "/"
10608                            + cpi.applicationInfo.uid + " for provider "
10609                            + name + ": launching app became null");
10610                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10611                            UserHandle.getUserId(cpi.applicationInfo.uid),
10612                            cpi.applicationInfo.packageName,
10613                            cpi.applicationInfo.uid, name);
10614                    return null;
10615                }
10616                try {
10617                    if (DEBUG_MU) Slog.v(TAG_MU,
10618                            "Waiting to start provider " + cpr
10619                            + " launchingApp=" + cpr.launchingApp);
10620                    if (conn != null) {
10621                        conn.waiting = true;
10622                    }
10623                    cpr.wait();
10624                } catch (InterruptedException ex) {
10625                } finally {
10626                    if (conn != null) {
10627                        conn.waiting = false;
10628                    }
10629                }
10630            }
10631        }
10632        return cpr != null ? cpr.newHolder(conn) : null;
10633    }
10634
10635    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10636            ProcessRecord r, final int userId) {
10637        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10638                cpi.packageName, userId)) {
10639
10640            final boolean callerForeground = r == null || r.setSchedGroup
10641                    != ProcessList.SCHED_GROUP_BACKGROUND;
10642
10643            // Show a permission review UI only for starting from a foreground app
10644            if (!callerForeground) {
10645                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10646                        + cpi.packageName + " requires a permissions review");
10647                return false;
10648            }
10649
10650            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10651            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10652                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10653            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10654
10655            if (DEBUG_PERMISSIONS_REVIEW) {
10656                Slog.i(TAG, "u" + userId + " Launching permission review "
10657                        + "for package " + cpi.packageName);
10658            }
10659
10660            final UserHandle userHandle = new UserHandle(userId);
10661            mHandler.post(new Runnable() {
10662                @Override
10663                public void run() {
10664                    mContext.startActivityAsUser(intent, userHandle);
10665                }
10666            });
10667
10668            return false;
10669        }
10670
10671        return true;
10672    }
10673
10674    PackageManagerInternal getPackageManagerInternalLocked() {
10675        if (mPackageManagerInt == null) {
10676            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10677        }
10678        return mPackageManagerInt;
10679    }
10680
10681    @Override
10682    public final ContentProviderHolder getContentProvider(
10683            IApplicationThread caller, String name, int userId, boolean stable) {
10684        enforceNotIsolatedCaller("getContentProvider");
10685        if (caller == null) {
10686            String msg = "null IApplicationThread when getting content provider "
10687                    + name;
10688            Slog.w(TAG, msg);
10689            throw new SecurityException(msg);
10690        }
10691        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10692        // with cross-user grant.
10693        return getContentProviderImpl(caller, name, null, stable, userId);
10694    }
10695
10696    public ContentProviderHolder getContentProviderExternal(
10697            String name, int userId, IBinder token) {
10698        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10699            "Do not have permission in call getContentProviderExternal()");
10700        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10701                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10702        return getContentProviderExternalUnchecked(name, token, userId);
10703    }
10704
10705    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10706            IBinder token, int userId) {
10707        return getContentProviderImpl(null, name, token, true, userId);
10708    }
10709
10710    /**
10711     * Drop a content provider from a ProcessRecord's bookkeeping
10712     */
10713    public void removeContentProvider(IBinder connection, boolean stable) {
10714        enforceNotIsolatedCaller("removeContentProvider");
10715        long ident = Binder.clearCallingIdentity();
10716        try {
10717            synchronized (this) {
10718                ContentProviderConnection conn;
10719                try {
10720                    conn = (ContentProviderConnection)connection;
10721                } catch (ClassCastException e) {
10722                    String msg ="removeContentProvider: " + connection
10723                            + " not a ContentProviderConnection";
10724                    Slog.w(TAG, msg);
10725                    throw new IllegalArgumentException(msg);
10726                }
10727                if (conn == null) {
10728                    throw new NullPointerException("connection is null");
10729                }
10730                if (decProviderCountLocked(conn, null, null, stable)) {
10731                    updateOomAdjLocked();
10732                }
10733            }
10734        } finally {
10735            Binder.restoreCallingIdentity(ident);
10736        }
10737    }
10738
10739    public void removeContentProviderExternal(String name, IBinder token) {
10740        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10741            "Do not have permission in call removeContentProviderExternal()");
10742        int userId = UserHandle.getCallingUserId();
10743        long ident = Binder.clearCallingIdentity();
10744        try {
10745            removeContentProviderExternalUnchecked(name, token, userId);
10746        } finally {
10747            Binder.restoreCallingIdentity(ident);
10748        }
10749    }
10750
10751    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10752        synchronized (this) {
10753            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10754            if(cpr == null) {
10755                //remove from mProvidersByClass
10756                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10757                return;
10758            }
10759
10760            //update content provider record entry info
10761            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10762            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10763            if (localCpr.hasExternalProcessHandles()) {
10764                if (localCpr.removeExternalProcessHandleLocked(token)) {
10765                    updateOomAdjLocked();
10766                } else {
10767                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10768                            + " with no external reference for token: "
10769                            + token + ".");
10770                }
10771            } else {
10772                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10773                        + " with no external references.");
10774            }
10775        }
10776    }
10777
10778    public final void publishContentProviders(IApplicationThread caller,
10779            List<ContentProviderHolder> providers) {
10780        if (providers == null) {
10781            return;
10782        }
10783
10784        enforceNotIsolatedCaller("publishContentProviders");
10785        synchronized (this) {
10786            final ProcessRecord r = getRecordForAppLocked(caller);
10787            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10788            if (r == null) {
10789                throw new SecurityException(
10790                        "Unable to find app for caller " + caller
10791                      + " (pid=" + Binder.getCallingPid()
10792                      + ") when publishing content providers");
10793            }
10794
10795            final long origId = Binder.clearCallingIdentity();
10796
10797            final int N = providers.size();
10798            for (int i = 0; i < N; i++) {
10799                ContentProviderHolder src = providers.get(i);
10800                if (src == null || src.info == null || src.provider == null) {
10801                    continue;
10802                }
10803                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10804                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10805                if (dst != null) {
10806                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10807                    mProviderMap.putProviderByClass(comp, dst);
10808                    String names[] = dst.info.authority.split(";");
10809                    for (int j = 0; j < names.length; j++) {
10810                        mProviderMap.putProviderByName(names[j], dst);
10811                    }
10812
10813                    int launchingCount = mLaunchingProviders.size();
10814                    int j;
10815                    boolean wasInLaunchingProviders = false;
10816                    for (j = 0; j < launchingCount; j++) {
10817                        if (mLaunchingProviders.get(j) == dst) {
10818                            mLaunchingProviders.remove(j);
10819                            wasInLaunchingProviders = true;
10820                            j--;
10821                            launchingCount--;
10822                        }
10823                    }
10824                    if (wasInLaunchingProviders) {
10825                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10826                    }
10827                    synchronized (dst) {
10828                        dst.provider = src.provider;
10829                        dst.proc = r;
10830                        dst.notifyAll();
10831                    }
10832                    updateOomAdjLocked(r);
10833                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10834                            src.info.authority);
10835                }
10836            }
10837
10838            Binder.restoreCallingIdentity(origId);
10839        }
10840    }
10841
10842    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10843        ContentProviderConnection conn;
10844        try {
10845            conn = (ContentProviderConnection)connection;
10846        } catch (ClassCastException e) {
10847            String msg ="refContentProvider: " + connection
10848                    + " not a ContentProviderConnection";
10849            Slog.w(TAG, msg);
10850            throw new IllegalArgumentException(msg);
10851        }
10852        if (conn == null) {
10853            throw new NullPointerException("connection is null");
10854        }
10855
10856        synchronized (this) {
10857            if (stable > 0) {
10858                conn.numStableIncs += stable;
10859            }
10860            stable = conn.stableCount + stable;
10861            if (stable < 0) {
10862                throw new IllegalStateException("stableCount < 0: " + stable);
10863            }
10864
10865            if (unstable > 0) {
10866                conn.numUnstableIncs += unstable;
10867            }
10868            unstable = conn.unstableCount + unstable;
10869            if (unstable < 0) {
10870                throw new IllegalStateException("unstableCount < 0: " + unstable);
10871            }
10872
10873            if ((stable+unstable) <= 0) {
10874                throw new IllegalStateException("ref counts can't go to zero here: stable="
10875                        + stable + " unstable=" + unstable);
10876            }
10877            conn.stableCount = stable;
10878            conn.unstableCount = unstable;
10879            return !conn.dead;
10880        }
10881    }
10882
10883    public void unstableProviderDied(IBinder connection) {
10884        ContentProviderConnection conn;
10885        try {
10886            conn = (ContentProviderConnection)connection;
10887        } catch (ClassCastException e) {
10888            String msg ="refContentProvider: " + connection
10889                    + " not a ContentProviderConnection";
10890            Slog.w(TAG, msg);
10891            throw new IllegalArgumentException(msg);
10892        }
10893        if (conn == null) {
10894            throw new NullPointerException("connection is null");
10895        }
10896
10897        // Safely retrieve the content provider associated with the connection.
10898        IContentProvider provider;
10899        synchronized (this) {
10900            provider = conn.provider.provider;
10901        }
10902
10903        if (provider == null) {
10904            // Um, yeah, we're way ahead of you.
10905            return;
10906        }
10907
10908        // Make sure the caller is being honest with us.
10909        if (provider.asBinder().pingBinder()) {
10910            // Er, no, still looks good to us.
10911            synchronized (this) {
10912                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10913                        + " says " + conn + " died, but we don't agree");
10914                return;
10915            }
10916        }
10917
10918        // Well look at that!  It's dead!
10919        synchronized (this) {
10920            if (conn.provider.provider != provider) {
10921                // But something changed...  good enough.
10922                return;
10923            }
10924
10925            ProcessRecord proc = conn.provider.proc;
10926            if (proc == null || proc.thread == null) {
10927                // Seems like the process is already cleaned up.
10928                return;
10929            }
10930
10931            // As far as we're concerned, this is just like receiving a
10932            // death notification...  just a bit prematurely.
10933            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10934                    + ") early provider death");
10935            final long ident = Binder.clearCallingIdentity();
10936            try {
10937                appDiedLocked(proc);
10938            } finally {
10939                Binder.restoreCallingIdentity(ident);
10940            }
10941        }
10942    }
10943
10944    @Override
10945    public void appNotRespondingViaProvider(IBinder connection) {
10946        enforceCallingPermission(
10947                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10948
10949        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10950        if (conn == null) {
10951            Slog.w(TAG, "ContentProviderConnection is null");
10952            return;
10953        }
10954
10955        final ProcessRecord host = conn.provider.proc;
10956        if (host == null) {
10957            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10958            return;
10959        }
10960
10961        mHandler.post(new Runnable() {
10962            @Override
10963            public void run() {
10964                mAppErrors.appNotResponding(host, null, null, false,
10965                        "ContentProvider not responding");
10966            }
10967        });
10968    }
10969
10970    public final void installSystemProviders() {
10971        List<ProviderInfo> providers;
10972        synchronized (this) {
10973            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10974            providers = generateApplicationProvidersLocked(app);
10975            if (providers != null) {
10976                for (int i=providers.size()-1; i>=0; i--) {
10977                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10978                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10979                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10980                                + ": not system .apk");
10981                        providers.remove(i);
10982                    }
10983                }
10984            }
10985        }
10986        if (providers != null) {
10987            mSystemThread.installSystemProviders(providers);
10988        }
10989
10990        mCoreSettingsObserver = new CoreSettingsObserver(this);
10991        mFontScaleSettingObserver = new FontScaleSettingObserver();
10992
10993        //mUsageStatsService.monitorPackages();
10994    }
10995
10996    private void startPersistentApps(int matchFlags) {
10997        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10998
10999        synchronized (this) {
11000            try {
11001                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11002                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11003                for (ApplicationInfo app : apps) {
11004                    if (!"android".equals(app.packageName)) {
11005                        addAppLocked(app, false, null /* ABI override */);
11006                    }
11007                }
11008            } catch (RemoteException ex) {
11009            }
11010        }
11011    }
11012
11013    /**
11014     * When a user is unlocked, we need to install encryption-unaware providers
11015     * belonging to any running apps.
11016     */
11017    private void installEncryptionUnawareProviders(int userId) {
11018        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
11019            // TODO: eventually pivot this back to look at current user state,
11020            // similar to the comment in UserManager.isUserUnlocked(), but for
11021            // now, if we started apps when "unlocked" then unaware providers
11022            // have already been spun up.
11023            return;
11024        }
11025
11026        // We're only interested in providers that are encryption unaware, and
11027        // we don't care about uninstalled apps, since there's no way they're
11028        // running at this point.
11029        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11030
11031        synchronized (this) {
11032            final int NP = mProcessNames.getMap().size();
11033            for (int ip = 0; ip < NP; ip++) {
11034                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11035                final int NA = apps.size();
11036                for (int ia = 0; ia < NA; ia++) {
11037                    final ProcessRecord app = apps.valueAt(ia);
11038                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11039
11040                    final int NG = app.pkgList.size();
11041                    for (int ig = 0; ig < NG; ig++) {
11042                        try {
11043                            final String pkgName = app.pkgList.keyAt(ig);
11044                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11045                                    .getPackageInfo(pkgName, matchFlags, userId);
11046                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11047                                for (ProviderInfo provInfo : pkgInfo.providers) {
11048                                    Log.v(TAG, "Installing " + provInfo);
11049                                    app.thread.scheduleInstallProvider(provInfo);
11050                                }
11051                            }
11052                        } catch (RemoteException ignored) {
11053                        }
11054                    }
11055                }
11056            }
11057        }
11058    }
11059
11060    /**
11061     * Allows apps to retrieve the MIME type of a URI.
11062     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11063     * users, then it does not need permission to access the ContentProvider.
11064     * Either, it needs cross-user uri grants.
11065     *
11066     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11067     *
11068     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11069     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11070     */
11071    public String getProviderMimeType(Uri uri, int userId) {
11072        enforceNotIsolatedCaller("getProviderMimeType");
11073        final String name = uri.getAuthority();
11074        int callingUid = Binder.getCallingUid();
11075        int callingPid = Binder.getCallingPid();
11076        long ident = 0;
11077        boolean clearedIdentity = false;
11078        synchronized (this) {
11079            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11080        }
11081        if (canClearIdentity(callingPid, callingUid, userId)) {
11082            clearedIdentity = true;
11083            ident = Binder.clearCallingIdentity();
11084        }
11085        ContentProviderHolder holder = null;
11086        try {
11087            holder = getContentProviderExternalUnchecked(name, null, userId);
11088            if (holder != null) {
11089                return holder.provider.getType(uri);
11090            }
11091        } catch (RemoteException e) {
11092            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11093            return null;
11094        } finally {
11095            // We need to clear the identity to call removeContentProviderExternalUnchecked
11096            if (!clearedIdentity) {
11097                ident = Binder.clearCallingIdentity();
11098            }
11099            try {
11100                if (holder != null) {
11101                    removeContentProviderExternalUnchecked(name, null, userId);
11102                }
11103            } finally {
11104                Binder.restoreCallingIdentity(ident);
11105            }
11106        }
11107
11108        return null;
11109    }
11110
11111    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11112        if (UserHandle.getUserId(callingUid) == userId) {
11113            return true;
11114        }
11115        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11116                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11117                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11118                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11119                return true;
11120        }
11121        return false;
11122    }
11123
11124    // =========================================================
11125    // GLOBAL MANAGEMENT
11126    // =========================================================
11127
11128    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11129            boolean isolated, int isolatedUid) {
11130        String proc = customProcess != null ? customProcess : info.processName;
11131        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11132        final int userId = UserHandle.getUserId(info.uid);
11133        int uid = info.uid;
11134        if (isolated) {
11135            if (isolatedUid == 0) {
11136                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11137                while (true) {
11138                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11139                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11140                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11141                    }
11142                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11143                    mNextIsolatedProcessUid++;
11144                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11145                        // No process for this uid, use it.
11146                        break;
11147                    }
11148                    stepsLeft--;
11149                    if (stepsLeft <= 0) {
11150                        return null;
11151                    }
11152                }
11153            } else {
11154                // Special case for startIsolatedProcess (internal only), where
11155                // the uid of the isolated process is specified by the caller.
11156                uid = isolatedUid;
11157            }
11158        }
11159        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11160        if (!mBooted && !mBooting
11161                && userId == UserHandle.USER_SYSTEM
11162                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11163            r.persistent = true;
11164        }
11165        addProcessNameLocked(r);
11166        return r;
11167    }
11168
11169    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11170            String abiOverride) {
11171        ProcessRecord app;
11172        if (!isolated) {
11173            app = getProcessRecordLocked(info.processName, info.uid, true);
11174        } else {
11175            app = null;
11176        }
11177
11178        if (app == null) {
11179            app = newProcessRecordLocked(info, null, isolated, 0);
11180            updateLruProcessLocked(app, false, null);
11181            updateOomAdjLocked();
11182        }
11183
11184        // This package really, really can not be stopped.
11185        try {
11186            AppGlobals.getPackageManager().setPackageStoppedState(
11187                    info.packageName, false, UserHandle.getUserId(app.uid));
11188        } catch (RemoteException e) {
11189        } catch (IllegalArgumentException e) {
11190            Slog.w(TAG, "Failed trying to unstop package "
11191                    + info.packageName + ": " + e);
11192        }
11193
11194        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11195            app.persistent = true;
11196            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11197        }
11198        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11199            mPersistentStartingProcesses.add(app);
11200            startProcessLocked(app, "added application", app.processName, abiOverride,
11201                    null /* entryPoint */, null /* entryPointArgs */);
11202        }
11203
11204        return app;
11205    }
11206
11207    public void unhandledBack() {
11208        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11209                "unhandledBack()");
11210
11211        synchronized(this) {
11212            final long origId = Binder.clearCallingIdentity();
11213            try {
11214                getFocusedStack().unhandledBackLocked();
11215            } finally {
11216                Binder.restoreCallingIdentity(origId);
11217            }
11218        }
11219    }
11220
11221    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11222        enforceNotIsolatedCaller("openContentUri");
11223        final int userId = UserHandle.getCallingUserId();
11224        String name = uri.getAuthority();
11225        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11226        ParcelFileDescriptor pfd = null;
11227        if (cph != null) {
11228            // We record the binder invoker's uid in thread-local storage before
11229            // going to the content provider to open the file.  Later, in the code
11230            // that handles all permissions checks, we look for this uid and use
11231            // that rather than the Activity Manager's own uid.  The effect is that
11232            // we do the check against the caller's permissions even though it looks
11233            // to the content provider like the Activity Manager itself is making
11234            // the request.
11235            Binder token = new Binder();
11236            sCallerIdentity.set(new Identity(
11237                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11238            try {
11239                pfd = cph.provider.openFile(null, uri, "r", null, token);
11240            } catch (FileNotFoundException e) {
11241                // do nothing; pfd will be returned null
11242            } finally {
11243                // Ensure that whatever happens, we clean up the identity state
11244                sCallerIdentity.remove();
11245                // Ensure we're done with the provider.
11246                removeContentProviderExternalUnchecked(name, null, userId);
11247            }
11248        } else {
11249            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11250        }
11251        return pfd;
11252    }
11253
11254    // Actually is sleeping or shutting down or whatever else in the future
11255    // is an inactive state.
11256    public boolean isSleepingOrShuttingDown() {
11257        return isSleeping() || mShuttingDown;
11258    }
11259
11260    public boolean isSleeping() {
11261        return mSleeping;
11262    }
11263
11264    void onWakefulnessChanged(int wakefulness) {
11265        synchronized(this) {
11266            mWakefulness = wakefulness;
11267            updateSleepIfNeededLocked();
11268        }
11269    }
11270
11271    void finishRunningVoiceLocked() {
11272        if (mRunningVoice != null) {
11273            mRunningVoice = null;
11274            mVoiceWakeLock.release();
11275            updateSleepIfNeededLocked();
11276        }
11277    }
11278
11279    void startTimeTrackingFocusedActivityLocked() {
11280        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11281            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11282        }
11283    }
11284
11285    void updateSleepIfNeededLocked() {
11286        if (mSleeping && !shouldSleepLocked()) {
11287            mSleeping = false;
11288            startTimeTrackingFocusedActivityLocked();
11289            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11290            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11291            updateOomAdjLocked();
11292        } else if (!mSleeping && shouldSleepLocked()) {
11293            mSleeping = true;
11294            if (mCurAppTimeTracker != null) {
11295                mCurAppTimeTracker.stop();
11296            }
11297            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11298            mStackSupervisor.goingToSleepLocked();
11299            updateOomAdjLocked();
11300
11301            // Initialize the wake times of all processes.
11302            checkExcessivePowerUsageLocked(false);
11303            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11304            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11305            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11306        }
11307    }
11308
11309    private boolean shouldSleepLocked() {
11310        // Resume applications while running a voice interactor.
11311        if (mRunningVoice != null) {
11312            return false;
11313        }
11314
11315        // TODO: Transform the lock screen state into a sleep token instead.
11316        switch (mWakefulness) {
11317            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11318            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11319            case PowerManagerInternal.WAKEFULNESS_DOZING:
11320                // Pause applications whenever the lock screen is shown or any sleep
11321                // tokens have been acquired.
11322                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11323            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11324            default:
11325                // If we're asleep then pause applications unconditionally.
11326                return true;
11327        }
11328    }
11329
11330    /** Pokes the task persister. */
11331    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11332        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11333    }
11334
11335    /** Notifies all listeners when the task stack has changed. */
11336    void notifyTaskStackChangedLocked() {
11337        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11338        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11339        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11340        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11341    }
11342
11343    /** Notifies all listeners when an Activity is pinned. */
11344    void notifyActivityPinnedLocked() {
11345        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11346        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11347    }
11348
11349    /**
11350     * Notifies all listeners when an attempt was made to start an an activity that is already
11351     * running in the pinned stack and the activity was not actually started, but the task is
11352     * either brought to the front or a new Intent is delivered to it.
11353     */
11354    void notifyPinnedActivityRestartAttemptLocked() {
11355        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11356        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11357    }
11358
11359    /** Notifies all listeners when the pinned stack animation ends. */
11360    @Override
11361    public void notifyPinnedStackAnimationEnded() {
11362        synchronized (this) {
11363            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11364            mHandler.obtainMessage(
11365                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11366        }
11367    }
11368
11369    @Override
11370    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11371        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11372    }
11373
11374    @Override
11375    public boolean shutdown(int timeout) {
11376        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11377                != PackageManager.PERMISSION_GRANTED) {
11378            throw new SecurityException("Requires permission "
11379                    + android.Manifest.permission.SHUTDOWN);
11380        }
11381
11382        boolean timedout = false;
11383
11384        synchronized(this) {
11385            mShuttingDown = true;
11386            updateEventDispatchingLocked();
11387            timedout = mStackSupervisor.shutdownLocked(timeout);
11388        }
11389
11390        mAppOpsService.shutdown();
11391        if (mUsageStatsService != null) {
11392            mUsageStatsService.prepareShutdown();
11393        }
11394        mBatteryStatsService.shutdown();
11395        synchronized (this) {
11396            mProcessStats.shutdownLocked();
11397            notifyTaskPersisterLocked(null, true);
11398        }
11399
11400        return timedout;
11401    }
11402
11403    public final void activitySlept(IBinder token) {
11404        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11405
11406        final long origId = Binder.clearCallingIdentity();
11407
11408        synchronized (this) {
11409            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11410            if (r != null) {
11411                mStackSupervisor.activitySleptLocked(r);
11412            }
11413        }
11414
11415        Binder.restoreCallingIdentity(origId);
11416    }
11417
11418    private String lockScreenShownToString() {
11419        switch (mLockScreenShown) {
11420            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11421            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11422            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11423            default: return "Unknown=" + mLockScreenShown;
11424        }
11425    }
11426
11427    void logLockScreen(String msg) {
11428        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11429                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11430                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11431                + " mSleeping=" + mSleeping);
11432    }
11433
11434    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11435        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11436        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11437        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11438            boolean wasRunningVoice = mRunningVoice != null;
11439            mRunningVoice = session;
11440            if (!wasRunningVoice) {
11441                mVoiceWakeLock.acquire();
11442                updateSleepIfNeededLocked();
11443            }
11444        }
11445    }
11446
11447    private void updateEventDispatchingLocked() {
11448        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11449    }
11450
11451    public void setLockScreenShown(boolean shown) {
11452        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11453                != PackageManager.PERMISSION_GRANTED) {
11454            throw new SecurityException("Requires permission "
11455                    + android.Manifest.permission.DEVICE_POWER);
11456        }
11457
11458        synchronized(this) {
11459            long ident = Binder.clearCallingIdentity();
11460            try {
11461                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11462                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11463                updateSleepIfNeededLocked();
11464            } finally {
11465                Binder.restoreCallingIdentity(ident);
11466            }
11467        }
11468    }
11469
11470    @Override
11471    public void notifyLockedProfile(@UserIdInt int userId) {
11472        try {
11473            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11474                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11475            }
11476        } catch (RemoteException ex) {
11477            throw new SecurityException("Fail to check is caller a privileged app", ex);
11478        }
11479
11480        synchronized (this) {
11481            if (mStackSupervisor.isUserLockedProfile(userId)) {
11482                final long ident = Binder.clearCallingIdentity();
11483                try {
11484                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11485                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11486                        // If there is no device lock, we will show the profile's credential page.
11487                        mActivityStarter.showConfirmDeviceCredential(userId);
11488                    } else {
11489                        // Showing launcher to avoid user entering credential twice.
11490                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11491                    }
11492                } finally {
11493                    Binder.restoreCallingIdentity(ident);
11494                }
11495            }
11496        }
11497    }
11498
11499    @Override
11500    public void stopAppSwitches() {
11501        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11502                != PackageManager.PERMISSION_GRANTED) {
11503            throw new SecurityException("viewquires permission "
11504                    + android.Manifest.permission.STOP_APP_SWITCHES);
11505        }
11506
11507        synchronized(this) {
11508            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11509                    + APP_SWITCH_DELAY_TIME;
11510            mDidAppSwitch = false;
11511            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11512            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11513            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11514        }
11515    }
11516
11517    public void resumeAppSwitches() {
11518        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11519                != PackageManager.PERMISSION_GRANTED) {
11520            throw new SecurityException("Requires permission "
11521                    + android.Manifest.permission.STOP_APP_SWITCHES);
11522        }
11523
11524        synchronized(this) {
11525            // Note that we don't execute any pending app switches... we will
11526            // let those wait until either the timeout, or the next start
11527            // activity request.
11528            mAppSwitchesAllowedTime = 0;
11529        }
11530    }
11531
11532    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11533            int callingPid, int callingUid, String name) {
11534        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11535            return true;
11536        }
11537
11538        int perm = checkComponentPermission(
11539                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11540                sourceUid, -1, true);
11541        if (perm == PackageManager.PERMISSION_GRANTED) {
11542            return true;
11543        }
11544
11545        // If the actual IPC caller is different from the logical source, then
11546        // also see if they are allowed to control app switches.
11547        if (callingUid != -1 && callingUid != sourceUid) {
11548            perm = checkComponentPermission(
11549                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11550                    callingUid, -1, true);
11551            if (perm == PackageManager.PERMISSION_GRANTED) {
11552                return true;
11553            }
11554        }
11555
11556        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11557        return false;
11558    }
11559
11560    public void setDebugApp(String packageName, boolean waitForDebugger,
11561            boolean persistent) {
11562        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11563                "setDebugApp()");
11564
11565        long ident = Binder.clearCallingIdentity();
11566        try {
11567            // Note that this is not really thread safe if there are multiple
11568            // callers into it at the same time, but that's not a situation we
11569            // care about.
11570            if (persistent) {
11571                final ContentResolver resolver = mContext.getContentResolver();
11572                Settings.Global.putString(
11573                    resolver, Settings.Global.DEBUG_APP,
11574                    packageName);
11575                Settings.Global.putInt(
11576                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11577                    waitForDebugger ? 1 : 0);
11578            }
11579
11580            synchronized (this) {
11581                if (!persistent) {
11582                    mOrigDebugApp = mDebugApp;
11583                    mOrigWaitForDebugger = mWaitForDebugger;
11584                }
11585                mDebugApp = packageName;
11586                mWaitForDebugger = waitForDebugger;
11587                mDebugTransient = !persistent;
11588                if (packageName != null) {
11589                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11590                            false, UserHandle.USER_ALL, "set debug app");
11591                }
11592            }
11593        } finally {
11594            Binder.restoreCallingIdentity(ident);
11595        }
11596    }
11597
11598    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11599        synchronized (this) {
11600            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11601            if (!isDebuggable) {
11602                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11603                    throw new SecurityException("Process not debuggable: " + app.packageName);
11604                }
11605            }
11606
11607            mTrackAllocationApp = processName;
11608        }
11609    }
11610
11611    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11612        synchronized (this) {
11613            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11614            if (!isDebuggable) {
11615                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11616                    throw new SecurityException("Process not debuggable: " + app.packageName);
11617                }
11618            }
11619            mProfileApp = processName;
11620            mProfileFile = profilerInfo.profileFile;
11621            if (mProfileFd != null) {
11622                try {
11623                    mProfileFd.close();
11624                } catch (IOException e) {
11625                }
11626                mProfileFd = null;
11627            }
11628            mProfileFd = profilerInfo.profileFd;
11629            mSamplingInterval = profilerInfo.samplingInterval;
11630            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11631            mProfileType = 0;
11632        }
11633    }
11634
11635    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11636        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11637        if (!isDebuggable) {
11638            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11639                throw new SecurityException("Process not debuggable: " + app.packageName);
11640            }
11641        }
11642        mNativeDebuggingApp = processName;
11643    }
11644
11645    @Override
11646    public void setAlwaysFinish(boolean enabled) {
11647        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11648                "setAlwaysFinish()");
11649
11650        long ident = Binder.clearCallingIdentity();
11651        try {
11652            Settings.Global.putInt(
11653                    mContext.getContentResolver(),
11654                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11655
11656            synchronized (this) {
11657                mAlwaysFinishActivities = enabled;
11658            }
11659        } finally {
11660            Binder.restoreCallingIdentity(ident);
11661        }
11662    }
11663
11664    @Override
11665    public void setLenientBackgroundCheck(boolean enabled) {
11666        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11667                "setLenientBackgroundCheck()");
11668
11669        long ident = Binder.clearCallingIdentity();
11670        try {
11671            Settings.Global.putInt(
11672                    mContext.getContentResolver(),
11673                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11674
11675            synchronized (this) {
11676                mLenientBackgroundCheck = enabled;
11677            }
11678        } finally {
11679            Binder.restoreCallingIdentity(ident);
11680        }
11681    }
11682
11683    @Override
11684    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11685        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11686                "setActivityController()");
11687        synchronized (this) {
11688            mController = controller;
11689            mControllerIsAMonkey = imAMonkey;
11690            Watchdog.getInstance().setActivityController(controller);
11691        }
11692    }
11693
11694    @Override
11695    public void setUserIsMonkey(boolean userIsMonkey) {
11696        synchronized (this) {
11697            synchronized (mPidsSelfLocked) {
11698                final int callingPid = Binder.getCallingPid();
11699                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11700                if (precessRecord == null) {
11701                    throw new SecurityException("Unknown process: " + callingPid);
11702                }
11703                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11704                    throw new SecurityException("Only an instrumentation process "
11705                            + "with a UiAutomation can call setUserIsMonkey");
11706                }
11707            }
11708            mUserIsMonkey = userIsMonkey;
11709        }
11710    }
11711
11712    @Override
11713    public boolean isUserAMonkey() {
11714        synchronized (this) {
11715            // If there is a controller also implies the user is a monkey.
11716            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11717        }
11718    }
11719
11720    public void requestBugReport(int bugreportType) {
11721        String service = null;
11722        switch (bugreportType) {
11723            case ActivityManager.BUGREPORT_OPTION_FULL:
11724                service = "bugreport";
11725                break;
11726            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11727                service = "bugreportplus";
11728                break;
11729            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11730                service = "bugreportremote";
11731                break;
11732        }
11733        if (service == null) {
11734            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11735                    + bugreportType);
11736        }
11737        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11738        SystemProperties.set("ctl.start", service);
11739    }
11740
11741    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11742        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11743    }
11744
11745    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11746        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11747            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11748        }
11749        return KEY_DISPATCHING_TIMEOUT;
11750    }
11751
11752    @Override
11753    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11754        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11755                != PackageManager.PERMISSION_GRANTED) {
11756            throw new SecurityException("Requires permission "
11757                    + android.Manifest.permission.FILTER_EVENTS);
11758        }
11759        ProcessRecord proc;
11760        long timeout;
11761        synchronized (this) {
11762            synchronized (mPidsSelfLocked) {
11763                proc = mPidsSelfLocked.get(pid);
11764            }
11765            timeout = getInputDispatchingTimeoutLocked(proc);
11766        }
11767
11768        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11769            return -1;
11770        }
11771
11772        return timeout;
11773    }
11774
11775    /**
11776     * Handle input dispatching timeouts.
11777     * Returns whether input dispatching should be aborted or not.
11778     */
11779    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11780            final ActivityRecord activity, final ActivityRecord parent,
11781            final boolean aboveSystem, String reason) {
11782        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11783                != PackageManager.PERMISSION_GRANTED) {
11784            throw new SecurityException("Requires permission "
11785                    + android.Manifest.permission.FILTER_EVENTS);
11786        }
11787
11788        final String annotation;
11789        if (reason == null) {
11790            annotation = "Input dispatching timed out";
11791        } else {
11792            annotation = "Input dispatching timed out (" + reason + ")";
11793        }
11794
11795        if (proc != null) {
11796            synchronized (this) {
11797                if (proc.debugging) {
11798                    return false;
11799                }
11800
11801                if (mDidDexOpt) {
11802                    // Give more time since we were dexopting.
11803                    mDidDexOpt = false;
11804                    return false;
11805                }
11806
11807                if (proc.instrumentationClass != null) {
11808                    Bundle info = new Bundle();
11809                    info.putString("shortMsg", "keyDispatchingTimedOut");
11810                    info.putString("longMsg", annotation);
11811                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11812                    return true;
11813                }
11814            }
11815            mHandler.post(new Runnable() {
11816                @Override
11817                public void run() {
11818                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11819                }
11820            });
11821        }
11822
11823        return true;
11824    }
11825
11826    @Override
11827    public Bundle getAssistContextExtras(int requestType) {
11828        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11829                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11830        if (pae == null) {
11831            return null;
11832        }
11833        synchronized (pae) {
11834            while (!pae.haveResult) {
11835                try {
11836                    pae.wait();
11837                } catch (InterruptedException e) {
11838                }
11839            }
11840        }
11841        synchronized (this) {
11842            buildAssistBundleLocked(pae, pae.result);
11843            mPendingAssistExtras.remove(pae);
11844            mUiHandler.removeCallbacks(pae);
11845        }
11846        return pae.extras;
11847    }
11848
11849    @Override
11850    public boolean isAssistDataAllowedOnCurrentActivity() {
11851        int userId;
11852        synchronized (this) {
11853            userId = mUserController.getCurrentUserIdLocked();
11854            ActivityRecord activity = getFocusedStack().topActivity();
11855            if (activity == null) {
11856                return false;
11857            }
11858            userId = activity.userId;
11859        }
11860        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11861                Context.DEVICE_POLICY_SERVICE);
11862        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11863    }
11864
11865    @Override
11866    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11867        long ident = Binder.clearCallingIdentity();
11868        try {
11869            synchronized (this) {
11870                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11871                ActivityRecord top = getFocusedStack().topActivity();
11872                if (top != caller) {
11873                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11874                            + " is not current top " + top);
11875                    return false;
11876                }
11877                if (!top.nowVisible) {
11878                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11879                            + " is not visible");
11880                    return false;
11881                }
11882            }
11883            AssistUtils utils = new AssistUtils(mContext);
11884            return utils.showSessionForActiveService(args,
11885                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11886        } finally {
11887            Binder.restoreCallingIdentity(ident);
11888        }
11889    }
11890
11891    @Override
11892    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11893            Bundle receiverExtras,
11894            IBinder activityToken, boolean focused) {
11895        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11896                activityToken, focused,
11897                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11898                != null;
11899    }
11900
11901    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11902            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11903            int userHandle, Bundle args, long timeout) {
11904        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11905                "enqueueAssistContext()");
11906        synchronized (this) {
11907            ActivityRecord activity = getFocusedStack().topActivity();
11908            if (activity == null) {
11909                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11910                return null;
11911            }
11912            if (activity.app == null || activity.app.thread == null) {
11913                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11914                return null;
11915            }
11916            if (focused) {
11917                if (activityToken != null) {
11918                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11919                    if (activity != caller) {
11920                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11921                                + " is not current top " + activity);
11922                        return null;
11923                    }
11924                }
11925            } else {
11926                activity = ActivityRecord.forTokenLocked(activityToken);
11927                if (activity == null) {
11928                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11929                            + " couldn't be found");
11930                    return null;
11931                }
11932            }
11933
11934            PendingAssistExtras pae;
11935            Bundle extras = new Bundle();
11936            if (args != null) {
11937                extras.putAll(args);
11938            }
11939            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11940            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11941            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11942                    userHandle);
11943            try {
11944                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11945                        requestType);
11946                mPendingAssistExtras.add(pae);
11947                mUiHandler.postDelayed(pae, timeout);
11948            } catch (RemoteException e) {
11949                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11950                return null;
11951            }
11952            return pae;
11953        }
11954    }
11955
11956    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11957        IResultReceiver receiver;
11958        synchronized (this) {
11959            mPendingAssistExtras.remove(pae);
11960            receiver = pae.receiver;
11961        }
11962        if (receiver != null) {
11963            // Caller wants result sent back to them.
11964            try {
11965                pae.receiver.send(0, null);
11966            } catch (RemoteException e) {
11967            }
11968        }
11969    }
11970
11971    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11972        if (result != null) {
11973            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11974        }
11975        if (pae.hint != null) {
11976            pae.extras.putBoolean(pae.hint, true);
11977        }
11978    }
11979
11980    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11981            AssistContent content, Uri referrer) {
11982        PendingAssistExtras pae = (PendingAssistExtras)token;
11983        synchronized (pae) {
11984            pae.result = extras;
11985            pae.structure = structure;
11986            pae.content = content;
11987            if (referrer != null) {
11988                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11989            }
11990            pae.haveResult = true;
11991            pae.notifyAll();
11992            if (pae.intent == null && pae.receiver == null) {
11993                // Caller is just waiting for the result.
11994                return;
11995            }
11996        }
11997
11998        // We are now ready to launch the assist activity.
11999        IResultReceiver sendReceiver = null;
12000        Bundle sendBundle = null;
12001        synchronized (this) {
12002            buildAssistBundleLocked(pae, extras);
12003            boolean exists = mPendingAssistExtras.remove(pae);
12004            mUiHandler.removeCallbacks(pae);
12005            if (!exists) {
12006                // Timed out.
12007                return;
12008            }
12009            if ((sendReceiver=pae.receiver) != null) {
12010                // Caller wants result sent back to them.
12011                sendBundle = new Bundle();
12012                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12013                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12014                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12015                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12016                        pae.receiverExtras);
12017            }
12018        }
12019        if (sendReceiver != null) {
12020            try {
12021                sendReceiver.send(0, sendBundle);
12022            } catch (RemoteException e) {
12023            }
12024            return;
12025        }
12026
12027        long ident = Binder.clearCallingIdentity();
12028        try {
12029            pae.intent.replaceExtras(pae.extras);
12030            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12031                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12032                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12033            closeSystemDialogs("assist");
12034            try {
12035                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12036            } catch (ActivityNotFoundException e) {
12037                Slog.w(TAG, "No activity to handle assist action.", e);
12038            }
12039        } finally {
12040            Binder.restoreCallingIdentity(ident);
12041        }
12042    }
12043
12044    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12045            Bundle args) {
12046        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12047                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12048    }
12049
12050    public void registerProcessObserver(IProcessObserver observer) {
12051        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12052                "registerProcessObserver()");
12053        synchronized (this) {
12054            mProcessObservers.register(observer);
12055        }
12056    }
12057
12058    @Override
12059    public void unregisterProcessObserver(IProcessObserver observer) {
12060        synchronized (this) {
12061            mProcessObservers.unregister(observer);
12062        }
12063    }
12064
12065    @Override
12066    public void registerUidObserver(IUidObserver observer, int which) {
12067        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12068                "registerUidObserver()");
12069        synchronized (this) {
12070            mUidObservers.register(observer, which);
12071        }
12072    }
12073
12074    @Override
12075    public void unregisterUidObserver(IUidObserver observer) {
12076        synchronized (this) {
12077            mUidObservers.unregister(observer);
12078        }
12079    }
12080
12081    @Override
12082    public boolean convertFromTranslucent(IBinder token) {
12083        final long origId = Binder.clearCallingIdentity();
12084        try {
12085            synchronized (this) {
12086                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12087                if (r == null) {
12088                    return false;
12089                }
12090                final boolean translucentChanged = r.changeWindowTranslucency(true);
12091                if (translucentChanged) {
12092                    r.task.stack.releaseBackgroundResources(r);
12093                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12094                }
12095                mWindowManager.setAppFullscreen(token, true);
12096                return translucentChanged;
12097            }
12098        } finally {
12099            Binder.restoreCallingIdentity(origId);
12100        }
12101    }
12102
12103    @Override
12104    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12105        final long origId = Binder.clearCallingIdentity();
12106        try {
12107            synchronized (this) {
12108                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12109                if (r == null) {
12110                    return false;
12111                }
12112                int index = r.task.mActivities.lastIndexOf(r);
12113                if (index > 0) {
12114                    ActivityRecord under = r.task.mActivities.get(index - 1);
12115                    under.returningOptions = options;
12116                }
12117                final boolean translucentChanged = r.changeWindowTranslucency(false);
12118                if (translucentChanged) {
12119                    r.task.stack.convertActivityToTranslucent(r);
12120                }
12121                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12122                mWindowManager.setAppFullscreen(token, false);
12123                return translucentChanged;
12124            }
12125        } finally {
12126            Binder.restoreCallingIdentity(origId);
12127        }
12128    }
12129
12130    @Override
12131    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12132        final long origId = Binder.clearCallingIdentity();
12133        try {
12134            synchronized (this) {
12135                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12136                if (r != null) {
12137                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12138                }
12139            }
12140            return false;
12141        } finally {
12142            Binder.restoreCallingIdentity(origId);
12143        }
12144    }
12145
12146    @Override
12147    public boolean isBackgroundVisibleBehind(IBinder token) {
12148        final long origId = Binder.clearCallingIdentity();
12149        try {
12150            synchronized (this) {
12151                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12152                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12153                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12154                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12155                return visible;
12156            }
12157        } finally {
12158            Binder.restoreCallingIdentity(origId);
12159        }
12160    }
12161
12162    @Override
12163    public ActivityOptions getActivityOptions(IBinder token) {
12164        final long origId = Binder.clearCallingIdentity();
12165        try {
12166            synchronized (this) {
12167                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12168                if (r != null) {
12169                    final ActivityOptions activityOptions = r.pendingOptions;
12170                    r.pendingOptions = null;
12171                    return activityOptions;
12172                }
12173                return null;
12174            }
12175        } finally {
12176            Binder.restoreCallingIdentity(origId);
12177        }
12178    }
12179
12180    @Override
12181    public void setImmersive(IBinder token, boolean immersive) {
12182        synchronized(this) {
12183            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12184            if (r == null) {
12185                throw new IllegalArgumentException();
12186            }
12187            r.immersive = immersive;
12188
12189            // update associated state if we're frontmost
12190            if (r == mFocusedActivity) {
12191                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12192                applyUpdateLockStateLocked(r);
12193            }
12194        }
12195    }
12196
12197    @Override
12198    public boolean isImmersive(IBinder token) {
12199        synchronized (this) {
12200            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12201            if (r == null) {
12202                throw new IllegalArgumentException();
12203            }
12204            return r.immersive;
12205        }
12206    }
12207
12208    @Override
12209    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12210        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12211            throw new UnsupportedOperationException("VR mode not supported on this device!");
12212        }
12213
12214        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12215
12216        ActivityRecord r;
12217        synchronized (this) {
12218            r = ActivityRecord.isInStackLocked(token);
12219        }
12220
12221        if (r == null) {
12222            throw new IllegalArgumentException();
12223        }
12224
12225        int err;
12226        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12227                VrManagerInternal.NO_ERROR) {
12228            return err;
12229        }
12230
12231        synchronized(this) {
12232            r.requestedVrComponent = (enabled) ? packageName : null;
12233
12234            // Update associated state if this activity is currently focused
12235            if (r == mFocusedActivity) {
12236                applyUpdateVrModeLocked(r);
12237            }
12238            return 0;
12239        }
12240    }
12241
12242    @Override
12243    public boolean isVrModePackageEnabled(ComponentName packageName) {
12244        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12245            throw new UnsupportedOperationException("VR mode not supported on this device!");
12246        }
12247
12248        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12249
12250        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12251                VrManagerInternal.NO_ERROR;
12252    }
12253
12254    public boolean isTopActivityImmersive() {
12255        enforceNotIsolatedCaller("startActivity");
12256        synchronized (this) {
12257            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12258            return (r != null) ? r.immersive : false;
12259        }
12260    }
12261
12262    @Override
12263    public boolean isTopOfTask(IBinder token) {
12264        synchronized (this) {
12265            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12266            if (r == null) {
12267                throw new IllegalArgumentException();
12268            }
12269            return r.task.getTopActivity() == r;
12270        }
12271    }
12272
12273    public final void enterSafeMode() {
12274        synchronized(this) {
12275            // It only makes sense to do this before the system is ready
12276            // and started launching other packages.
12277            if (!mSystemReady) {
12278                try {
12279                    AppGlobals.getPackageManager().enterSafeMode();
12280                } catch (RemoteException e) {
12281                }
12282            }
12283
12284            mSafeMode = true;
12285        }
12286    }
12287
12288    public final void showSafeModeOverlay() {
12289        View v = LayoutInflater.from(mContext).inflate(
12290                com.android.internal.R.layout.safe_mode, null);
12291        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12292        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12293        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12294        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12295        lp.gravity = Gravity.BOTTOM | Gravity.START;
12296        lp.format = v.getBackground().getOpacity();
12297        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12298                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12299        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12300        ((WindowManager)mContext.getSystemService(
12301                Context.WINDOW_SERVICE)).addView(v, lp);
12302    }
12303
12304    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12305        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12306            return;
12307        }
12308        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12309        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12310        synchronized (stats) {
12311            if (mBatteryStatsService.isOnBattery()) {
12312                mBatteryStatsService.enforceCallingPermission();
12313                int MY_UID = Binder.getCallingUid();
12314                final int uid;
12315                if (sender == null) {
12316                    uid = sourceUid;
12317                } else {
12318                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12319                }
12320                BatteryStatsImpl.Uid.Pkg pkg =
12321                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12322                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12323                pkg.noteWakeupAlarmLocked(tag);
12324            }
12325        }
12326    }
12327
12328    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12329        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12330            return;
12331        }
12332        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12333        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12334        synchronized (stats) {
12335            mBatteryStatsService.enforceCallingPermission();
12336            int MY_UID = Binder.getCallingUid();
12337            final int uid;
12338            if (sender == null) {
12339                uid = sourceUid;
12340            } else {
12341                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12342            }
12343            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12344        }
12345    }
12346
12347    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12348        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12349            return;
12350        }
12351        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12352        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12353        synchronized (stats) {
12354            mBatteryStatsService.enforceCallingPermission();
12355            int MY_UID = Binder.getCallingUid();
12356            final int uid;
12357            if (sender == null) {
12358                uid = sourceUid;
12359            } else {
12360                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12361            }
12362            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12363        }
12364    }
12365
12366    public boolean killPids(int[] pids, String pReason, boolean secure) {
12367        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12368            throw new SecurityException("killPids only available to the system");
12369        }
12370        String reason = (pReason == null) ? "Unknown" : pReason;
12371        // XXX Note: don't acquire main activity lock here, because the window
12372        // manager calls in with its locks held.
12373
12374        boolean killed = false;
12375        synchronized (mPidsSelfLocked) {
12376            int worstType = 0;
12377            for (int i=0; i<pids.length; i++) {
12378                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12379                if (proc != null) {
12380                    int type = proc.setAdj;
12381                    if (type > worstType) {
12382                        worstType = type;
12383                    }
12384                }
12385            }
12386
12387            // If the worst oom_adj is somewhere in the cached proc LRU range,
12388            // then constrain it so we will kill all cached procs.
12389            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12390                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12391                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12392            }
12393
12394            // If this is not a secure call, don't let it kill processes that
12395            // are important.
12396            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12397                worstType = ProcessList.SERVICE_ADJ;
12398            }
12399
12400            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12401            for (int i=0; i<pids.length; i++) {
12402                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12403                if (proc == null) {
12404                    continue;
12405                }
12406                int adj = proc.setAdj;
12407                if (adj >= worstType && !proc.killedByAm) {
12408                    proc.kill(reason, true);
12409                    killed = true;
12410                }
12411            }
12412        }
12413        return killed;
12414    }
12415
12416    @Override
12417    public void killUid(int appId, int userId, String reason) {
12418        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12419        synchronized (this) {
12420            final long identity = Binder.clearCallingIdentity();
12421            try {
12422                killPackageProcessesLocked(null, appId, userId,
12423                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12424                        reason != null ? reason : "kill uid");
12425            } finally {
12426                Binder.restoreCallingIdentity(identity);
12427            }
12428        }
12429    }
12430
12431    @Override
12432    public boolean killProcessesBelowForeground(String reason) {
12433        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12434            throw new SecurityException("killProcessesBelowForeground() only available to system");
12435        }
12436
12437        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12438    }
12439
12440    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12441        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12442            throw new SecurityException("killProcessesBelowAdj() only available to system");
12443        }
12444
12445        boolean killed = false;
12446        synchronized (mPidsSelfLocked) {
12447            final int size = mPidsSelfLocked.size();
12448            for (int i = 0; i < size; i++) {
12449                final int pid = mPidsSelfLocked.keyAt(i);
12450                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12451                if (proc == null) continue;
12452
12453                final int adj = proc.setAdj;
12454                if (adj > belowAdj && !proc.killedByAm) {
12455                    proc.kill(reason, true);
12456                    killed = true;
12457                }
12458            }
12459        }
12460        return killed;
12461    }
12462
12463    @Override
12464    public void hang(final IBinder who, boolean allowRestart) {
12465        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12466                != PackageManager.PERMISSION_GRANTED) {
12467            throw new SecurityException("Requires permission "
12468                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12469        }
12470
12471        final IBinder.DeathRecipient death = new DeathRecipient() {
12472            @Override
12473            public void binderDied() {
12474                synchronized (this) {
12475                    notifyAll();
12476                }
12477            }
12478        };
12479
12480        try {
12481            who.linkToDeath(death, 0);
12482        } catch (RemoteException e) {
12483            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12484            return;
12485        }
12486
12487        synchronized (this) {
12488            Watchdog.getInstance().setAllowRestart(allowRestart);
12489            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12490            synchronized (death) {
12491                while (who.isBinderAlive()) {
12492                    try {
12493                        death.wait();
12494                    } catch (InterruptedException e) {
12495                    }
12496                }
12497            }
12498            Watchdog.getInstance().setAllowRestart(true);
12499        }
12500    }
12501
12502    @Override
12503    public void restart() {
12504        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12505                != PackageManager.PERMISSION_GRANTED) {
12506            throw new SecurityException("Requires permission "
12507                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12508        }
12509
12510        Log.i(TAG, "Sending shutdown broadcast...");
12511
12512        BroadcastReceiver br = new BroadcastReceiver() {
12513            @Override public void onReceive(Context context, Intent intent) {
12514                // Now the broadcast is done, finish up the low-level shutdown.
12515                Log.i(TAG, "Shutting down activity manager...");
12516                shutdown(10000);
12517                Log.i(TAG, "Shutdown complete, restarting!");
12518                Process.killProcess(Process.myPid());
12519                System.exit(10);
12520            }
12521        };
12522
12523        // First send the high-level shut down broadcast.
12524        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12525        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12526        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12527        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12528        mContext.sendOrderedBroadcastAsUser(intent,
12529                UserHandle.ALL, null, br, mHandler, 0, null, null);
12530        */
12531        br.onReceive(mContext, intent);
12532    }
12533
12534    private long getLowRamTimeSinceIdle(long now) {
12535        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12536    }
12537
12538    @Override
12539    public void performIdleMaintenance() {
12540        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12541                != PackageManager.PERMISSION_GRANTED) {
12542            throw new SecurityException("Requires permission "
12543                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12544        }
12545
12546        synchronized (this) {
12547            final long now = SystemClock.uptimeMillis();
12548            final long timeSinceLastIdle = now - mLastIdleTime;
12549            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12550            mLastIdleTime = now;
12551            mLowRamTimeSinceLastIdle = 0;
12552            if (mLowRamStartTime != 0) {
12553                mLowRamStartTime = now;
12554            }
12555
12556            StringBuilder sb = new StringBuilder(128);
12557            sb.append("Idle maintenance over ");
12558            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12559            sb.append(" low RAM for ");
12560            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12561            Slog.i(TAG, sb.toString());
12562
12563            // If at least 1/3 of our time since the last idle period has been spent
12564            // with RAM low, then we want to kill processes.
12565            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12566
12567            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12568                ProcessRecord proc = mLruProcesses.get(i);
12569                if (proc.notCachedSinceIdle) {
12570                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12571                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12572                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12573                        if (doKilling && proc.initialIdlePss != 0
12574                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12575                            sb = new StringBuilder(128);
12576                            sb.append("Kill");
12577                            sb.append(proc.processName);
12578                            sb.append(" in idle maint: pss=");
12579                            sb.append(proc.lastPss);
12580                            sb.append(", swapPss=");
12581                            sb.append(proc.lastSwapPss);
12582                            sb.append(", initialPss=");
12583                            sb.append(proc.initialIdlePss);
12584                            sb.append(", period=");
12585                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12586                            sb.append(", lowRamPeriod=");
12587                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12588                            Slog.wtfQuiet(TAG, sb.toString());
12589                            proc.kill("idle maint (pss " + proc.lastPss
12590                                    + " from " + proc.initialIdlePss + ")", true);
12591                        }
12592                    }
12593                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12594                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12595                    proc.notCachedSinceIdle = true;
12596                    proc.initialIdlePss = 0;
12597                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12598                            mTestPssMode, isSleeping(), now);
12599                }
12600            }
12601
12602            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12603            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12604        }
12605    }
12606
12607    private void retrieveSettings() {
12608        final ContentResolver resolver = mContext.getContentResolver();
12609        final boolean freeformWindowManagement =
12610                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12611                        || Settings.Global.getInt(
12612                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12613        final boolean supportsPictureInPicture =
12614                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12615
12616        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12617        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12618        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12619        final boolean alwaysFinishActivities =
12620                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12621        final boolean lenientBackgroundCheck =
12622                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12623        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12624        final boolean forceResizable = Settings.Global.getInt(
12625                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12626        // Transfer any global setting for forcing RTL layout, into a System Property
12627        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12628
12629        final Configuration configuration = new Configuration();
12630        Settings.System.getConfiguration(resolver, configuration);
12631        if (forceRtl) {
12632            // This will take care of setting the correct layout direction flags
12633            configuration.setLayoutDirection(configuration.locale);
12634        }
12635
12636        synchronized (this) {
12637            mDebugApp = mOrigDebugApp = debugApp;
12638            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12639            mAlwaysFinishActivities = alwaysFinishActivities;
12640            mLenientBackgroundCheck = lenientBackgroundCheck;
12641            mForceResizableActivities = forceResizable;
12642            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12643            if (supportsMultiWindow || forceResizable) {
12644                mSupportsMultiWindow = true;
12645                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12646                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12647            } else {
12648                mSupportsMultiWindow = false;
12649                mSupportsFreeformWindowManagement = false;
12650                mSupportsPictureInPicture = false;
12651            }
12652            // This happens before any activities are started, so we can
12653            // change mConfiguration in-place.
12654            updateConfigurationLocked(configuration, null, true);
12655            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12656                    "Initial config: " + mConfiguration);
12657
12658            // Load resources only after the current configuration has been set.
12659            final Resources res = mContext.getResources();
12660            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12661            mThumbnailWidth = res.getDimensionPixelSize(
12662                    com.android.internal.R.dimen.thumbnail_width);
12663            mThumbnailHeight = res.getDimensionPixelSize(
12664                    com.android.internal.R.dimen.thumbnail_height);
12665            mFullscreenThumbnailScale = res.getFraction(
12666                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12667            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12668                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12669            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12670                    com.android.internal.R.string.config_appsNotReportingCrashes));
12671        }
12672    }
12673
12674    public boolean testIsSystemReady() {
12675        // no need to synchronize(this) just to read & return the value
12676        return mSystemReady;
12677    }
12678
12679    public void systemReady(final Runnable goingCallback) {
12680        synchronized(this) {
12681            if (mSystemReady) {
12682                // If we're done calling all the receivers, run the next "boot phase" passed in
12683                // by the SystemServer
12684                if (goingCallback != null) {
12685                    goingCallback.run();
12686                }
12687                return;
12688            }
12689
12690            mLocalDeviceIdleController
12691                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12692
12693            // Make sure we have the current profile info, since it is needed for security checks.
12694            mUserController.onSystemReady();
12695            mRecentTasks.onSystemReadyLocked();
12696            mAppOpsService.systemReady();
12697            mSystemReady = true;
12698        }
12699
12700        ArrayList<ProcessRecord> procsToKill = null;
12701        synchronized(mPidsSelfLocked) {
12702            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12703                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12704                if (!isAllowedWhileBooting(proc.info)){
12705                    if (procsToKill == null) {
12706                        procsToKill = new ArrayList<ProcessRecord>();
12707                    }
12708                    procsToKill.add(proc);
12709                }
12710            }
12711        }
12712
12713        synchronized(this) {
12714            if (procsToKill != null) {
12715                for (int i=procsToKill.size()-1; i>=0; i--) {
12716                    ProcessRecord proc = procsToKill.get(i);
12717                    Slog.i(TAG, "Removing system update proc: " + proc);
12718                    removeProcessLocked(proc, true, false, "system update done");
12719                }
12720            }
12721
12722            // Now that we have cleaned up any update processes, we
12723            // are ready to start launching real processes and know that
12724            // we won't trample on them any more.
12725            mProcessesReady = true;
12726        }
12727
12728        Slog.i(TAG, "System now ready");
12729        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12730            SystemClock.uptimeMillis());
12731
12732        synchronized(this) {
12733            // Make sure we have no pre-ready processes sitting around.
12734
12735            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12736                ResolveInfo ri = mContext.getPackageManager()
12737                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12738                                STOCK_PM_FLAGS);
12739                CharSequence errorMsg = null;
12740                if (ri != null) {
12741                    ActivityInfo ai = ri.activityInfo;
12742                    ApplicationInfo app = ai.applicationInfo;
12743                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12744                        mTopAction = Intent.ACTION_FACTORY_TEST;
12745                        mTopData = null;
12746                        mTopComponent = new ComponentName(app.packageName,
12747                                ai.name);
12748                    } else {
12749                        errorMsg = mContext.getResources().getText(
12750                                com.android.internal.R.string.factorytest_not_system);
12751                    }
12752                } else {
12753                    errorMsg = mContext.getResources().getText(
12754                            com.android.internal.R.string.factorytest_no_action);
12755                }
12756                if (errorMsg != null) {
12757                    mTopAction = null;
12758                    mTopData = null;
12759                    mTopComponent = null;
12760                    Message msg = Message.obtain();
12761                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12762                    msg.getData().putCharSequence("msg", errorMsg);
12763                    mUiHandler.sendMessage(msg);
12764                }
12765            }
12766        }
12767
12768        retrieveSettings();
12769        final int currentUserId;
12770        synchronized (this) {
12771            currentUserId = mUserController.getCurrentUserIdLocked();
12772            readGrantedUriPermissionsLocked();
12773        }
12774
12775        if (goingCallback != null) goingCallback.run();
12776
12777        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12778                Integer.toString(currentUserId), currentUserId);
12779        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12780                Integer.toString(currentUserId), currentUserId);
12781        mSystemServiceManager.startUser(currentUserId);
12782
12783        synchronized (this) {
12784            // Only start up encryption-aware persistent apps; once user is
12785            // unlocked we'll come back around and start unaware apps
12786            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12787
12788            // Start up initial activity.
12789            mBooting = true;
12790            // Enable home activity for system user, so that the system can always boot
12791            if (UserManager.isSplitSystemUser()) {
12792                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12793                try {
12794                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12795                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12796                            UserHandle.USER_SYSTEM);
12797                } catch (RemoteException e) {
12798                    throw e.rethrowAsRuntimeException();
12799                }
12800            }
12801            startHomeActivityLocked(currentUserId, "systemReady");
12802
12803            try {
12804                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12805                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12806                            + " data partition or your device will be unstable.");
12807                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12808                }
12809            } catch (RemoteException e) {
12810            }
12811
12812            if (!Build.isBuildConsistent()) {
12813                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12814                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12815            }
12816
12817            long ident = Binder.clearCallingIdentity();
12818            try {
12819                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12820                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12821                        | Intent.FLAG_RECEIVER_FOREGROUND);
12822                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12823                broadcastIntentLocked(null, null, intent,
12824                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12825                        null, false, false, MY_PID, Process.SYSTEM_UID,
12826                        currentUserId);
12827                intent = new Intent(Intent.ACTION_USER_STARTING);
12828                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12829                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12830                broadcastIntentLocked(null, null, intent,
12831                        null, new IIntentReceiver.Stub() {
12832                            @Override
12833                            public void performReceive(Intent intent, int resultCode, String data,
12834                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12835                                    throws RemoteException {
12836                            }
12837                        }, 0, null, null,
12838                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12839                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12840            } catch (Throwable t) {
12841                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12842            } finally {
12843                Binder.restoreCallingIdentity(ident);
12844            }
12845            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12846            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12847        }
12848    }
12849
12850    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12851        synchronized (this) {
12852            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12853        }
12854    }
12855
12856    void skipCurrentReceiverLocked(ProcessRecord app) {
12857        for (BroadcastQueue queue : mBroadcastQueues) {
12858            queue.skipCurrentReceiverLocked(app);
12859        }
12860    }
12861
12862    /**
12863     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12864     * The application process will exit immediately after this call returns.
12865     * @param app object of the crashing app, null for the system server
12866     * @param crashInfo describing the exception
12867     */
12868    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12869        ProcessRecord r = findAppProcess(app, "Crash");
12870        final String processName = app == null ? "system_server"
12871                : (r == null ? "unknown" : r.processName);
12872
12873        handleApplicationCrashInner("crash", r, processName, crashInfo);
12874    }
12875
12876    /* Native crash reporting uses this inner version because it needs to be somewhat
12877     * decoupled from the AM-managed cleanup lifecycle
12878     */
12879    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12880            ApplicationErrorReport.CrashInfo crashInfo) {
12881        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12882                UserHandle.getUserId(Binder.getCallingUid()), processName,
12883                r == null ? -1 : r.info.flags,
12884                crashInfo.exceptionClassName,
12885                crashInfo.exceptionMessage,
12886                crashInfo.throwFileName,
12887                crashInfo.throwLineNumber);
12888
12889        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12890
12891        mAppErrors.crashApplication(r, crashInfo);
12892    }
12893
12894    public void handleApplicationStrictModeViolation(
12895            IBinder app,
12896            int violationMask,
12897            StrictMode.ViolationInfo info) {
12898        ProcessRecord r = findAppProcess(app, "StrictMode");
12899        if (r == null) {
12900            return;
12901        }
12902
12903        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12904            Integer stackFingerprint = info.hashCode();
12905            boolean logIt = true;
12906            synchronized (mAlreadyLoggedViolatedStacks) {
12907                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12908                    logIt = false;
12909                    // TODO: sub-sample into EventLog for these, with
12910                    // the info.durationMillis?  Then we'd get
12911                    // the relative pain numbers, without logging all
12912                    // the stack traces repeatedly.  We'd want to do
12913                    // likewise in the client code, which also does
12914                    // dup suppression, before the Binder call.
12915                } else {
12916                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12917                        mAlreadyLoggedViolatedStacks.clear();
12918                    }
12919                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12920                }
12921            }
12922            if (logIt) {
12923                logStrictModeViolationToDropBox(r, info);
12924            }
12925        }
12926
12927        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12928            AppErrorResult result = new AppErrorResult();
12929            synchronized (this) {
12930                final long origId = Binder.clearCallingIdentity();
12931
12932                Message msg = Message.obtain();
12933                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12934                HashMap<String, Object> data = new HashMap<String, Object>();
12935                data.put("result", result);
12936                data.put("app", r);
12937                data.put("violationMask", violationMask);
12938                data.put("info", info);
12939                msg.obj = data;
12940                mUiHandler.sendMessage(msg);
12941
12942                Binder.restoreCallingIdentity(origId);
12943            }
12944            int res = result.get();
12945            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12946        }
12947    }
12948
12949    // Depending on the policy in effect, there could be a bunch of
12950    // these in quick succession so we try to batch these together to
12951    // minimize disk writes, number of dropbox entries, and maximize
12952    // compression, by having more fewer, larger records.
12953    private void logStrictModeViolationToDropBox(
12954            ProcessRecord process,
12955            StrictMode.ViolationInfo info) {
12956        if (info == null) {
12957            return;
12958        }
12959        final boolean isSystemApp = process == null ||
12960                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12961                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12962        final String processName = process == null ? "unknown" : process.processName;
12963        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12964        final DropBoxManager dbox = (DropBoxManager)
12965                mContext.getSystemService(Context.DROPBOX_SERVICE);
12966
12967        // Exit early if the dropbox isn't configured to accept this report type.
12968        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12969
12970        boolean bufferWasEmpty;
12971        boolean needsFlush;
12972        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12973        synchronized (sb) {
12974            bufferWasEmpty = sb.length() == 0;
12975            appendDropBoxProcessHeaders(process, processName, sb);
12976            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12977            sb.append("System-App: ").append(isSystemApp).append("\n");
12978            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12979            if (info.violationNumThisLoop != 0) {
12980                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12981            }
12982            if (info.numAnimationsRunning != 0) {
12983                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12984            }
12985            if (info.broadcastIntentAction != null) {
12986                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12987            }
12988            if (info.durationMillis != -1) {
12989                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12990            }
12991            if (info.numInstances != -1) {
12992                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12993            }
12994            if (info.tags != null) {
12995                for (String tag : info.tags) {
12996                    sb.append("Span-Tag: ").append(tag).append("\n");
12997                }
12998            }
12999            sb.append("\n");
13000            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13001                sb.append(info.crashInfo.stackTrace);
13002                sb.append("\n");
13003            }
13004            if (info.message != null) {
13005                sb.append(info.message);
13006                sb.append("\n");
13007            }
13008
13009            // Only buffer up to ~64k.  Various logging bits truncate
13010            // things at 128k.
13011            needsFlush = (sb.length() > 64 * 1024);
13012        }
13013
13014        // Flush immediately if the buffer's grown too large, or this
13015        // is a non-system app.  Non-system apps are isolated with a
13016        // different tag & policy and not batched.
13017        //
13018        // Batching is useful during internal testing with
13019        // StrictMode settings turned up high.  Without batching,
13020        // thousands of separate files could be created on boot.
13021        if (!isSystemApp || needsFlush) {
13022            new Thread("Error dump: " + dropboxTag) {
13023                @Override
13024                public void run() {
13025                    String report;
13026                    synchronized (sb) {
13027                        report = sb.toString();
13028                        sb.delete(0, sb.length());
13029                        sb.trimToSize();
13030                    }
13031                    if (report.length() != 0) {
13032                        dbox.addText(dropboxTag, report);
13033                    }
13034                }
13035            }.start();
13036            return;
13037        }
13038
13039        // System app batching:
13040        if (!bufferWasEmpty) {
13041            // An existing dropbox-writing thread is outstanding, so
13042            // we don't need to start it up.  The existing thread will
13043            // catch the buffer appends we just did.
13044            return;
13045        }
13046
13047        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13048        // (After this point, we shouldn't access AMS internal data structures.)
13049        new Thread("Error dump: " + dropboxTag) {
13050            @Override
13051            public void run() {
13052                // 5 second sleep to let stacks arrive and be batched together
13053                try {
13054                    Thread.sleep(5000);  // 5 seconds
13055                } catch (InterruptedException e) {}
13056
13057                String errorReport;
13058                synchronized (mStrictModeBuffer) {
13059                    errorReport = mStrictModeBuffer.toString();
13060                    if (errorReport.length() == 0) {
13061                        return;
13062                    }
13063                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13064                    mStrictModeBuffer.trimToSize();
13065                }
13066                dbox.addText(dropboxTag, errorReport);
13067            }
13068        }.start();
13069    }
13070
13071    /**
13072     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13073     * @param app object of the crashing app, null for the system server
13074     * @param tag reported by the caller
13075     * @param system whether this wtf is coming from the system
13076     * @param crashInfo describing the context of the error
13077     * @return true if the process should exit immediately (WTF is fatal)
13078     */
13079    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13080            final ApplicationErrorReport.CrashInfo crashInfo) {
13081        final int callingUid = Binder.getCallingUid();
13082        final int callingPid = Binder.getCallingPid();
13083
13084        if (system) {
13085            // If this is coming from the system, we could very well have low-level
13086            // system locks held, so we want to do this all asynchronously.  And we
13087            // never want this to become fatal, so there is that too.
13088            mHandler.post(new Runnable() {
13089                @Override public void run() {
13090                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13091                }
13092            });
13093            return false;
13094        }
13095
13096        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13097                crashInfo);
13098
13099        if (r != null && r.pid != Process.myPid() &&
13100                Settings.Global.getInt(mContext.getContentResolver(),
13101                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13102            mAppErrors.crashApplication(r, crashInfo);
13103            return true;
13104        } else {
13105            return false;
13106        }
13107    }
13108
13109    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13110            final ApplicationErrorReport.CrashInfo crashInfo) {
13111        final ProcessRecord r = findAppProcess(app, "WTF");
13112        final String processName = app == null ? "system_server"
13113                : (r == null ? "unknown" : r.processName);
13114
13115        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13116                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13117
13118        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13119
13120        return r;
13121    }
13122
13123    /**
13124     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13125     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13126     */
13127    private ProcessRecord findAppProcess(IBinder app, String reason) {
13128        if (app == null) {
13129            return null;
13130        }
13131
13132        synchronized (this) {
13133            final int NP = mProcessNames.getMap().size();
13134            for (int ip=0; ip<NP; ip++) {
13135                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13136                final int NA = apps.size();
13137                for (int ia=0; ia<NA; ia++) {
13138                    ProcessRecord p = apps.valueAt(ia);
13139                    if (p.thread != null && p.thread.asBinder() == app) {
13140                        return p;
13141                    }
13142                }
13143            }
13144
13145            Slog.w(TAG, "Can't find mystery application for " + reason
13146                    + " from pid=" + Binder.getCallingPid()
13147                    + " uid=" + Binder.getCallingUid() + ": " + app);
13148            return null;
13149        }
13150    }
13151
13152    /**
13153     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13154     * to append various headers to the dropbox log text.
13155     */
13156    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13157            StringBuilder sb) {
13158        // Watchdog thread ends up invoking this function (with
13159        // a null ProcessRecord) to add the stack file to dropbox.
13160        // Do not acquire a lock on this (am) in such cases, as it
13161        // could cause a potential deadlock, if and when watchdog
13162        // is invoked due to unavailability of lock on am and it
13163        // would prevent watchdog from killing system_server.
13164        if (process == null) {
13165            sb.append("Process: ").append(processName).append("\n");
13166            return;
13167        }
13168        // Note: ProcessRecord 'process' is guarded by the service
13169        // instance.  (notably process.pkgList, which could otherwise change
13170        // concurrently during execution of this method)
13171        synchronized (this) {
13172            sb.append("Process: ").append(processName).append("\n");
13173            int flags = process.info.flags;
13174            IPackageManager pm = AppGlobals.getPackageManager();
13175            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13176            for (int ip=0; ip<process.pkgList.size(); ip++) {
13177                String pkg = process.pkgList.keyAt(ip);
13178                sb.append("Package: ").append(pkg);
13179                try {
13180                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13181                    if (pi != null) {
13182                        sb.append(" v").append(pi.versionCode);
13183                        if (pi.versionName != null) {
13184                            sb.append(" (").append(pi.versionName).append(")");
13185                        }
13186                    }
13187                } catch (RemoteException e) {
13188                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13189                }
13190                sb.append("\n");
13191            }
13192        }
13193    }
13194
13195    private static String processClass(ProcessRecord process) {
13196        if (process == null || process.pid == MY_PID) {
13197            return "system_server";
13198        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13199            return "system_app";
13200        } else {
13201            return "data_app";
13202        }
13203    }
13204
13205    private volatile long mWtfClusterStart;
13206    private volatile int mWtfClusterCount;
13207
13208    /**
13209     * Write a description of an error (crash, WTF, ANR) to the drop box.
13210     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13211     * @param process which caused the error, null means the system server
13212     * @param activity which triggered the error, null if unknown
13213     * @param parent activity related to the error, null if unknown
13214     * @param subject line related to the error, null if absent
13215     * @param report in long form describing the error, null if absent
13216     * @param logFile to include in the report, null if none
13217     * @param crashInfo giving an application stack trace, null if absent
13218     */
13219    public void addErrorToDropBox(String eventType,
13220            ProcessRecord process, String processName, ActivityRecord activity,
13221            ActivityRecord parent, String subject,
13222            final String report, final File logFile,
13223            final ApplicationErrorReport.CrashInfo crashInfo) {
13224        // NOTE -- this must never acquire the ActivityManagerService lock,
13225        // otherwise the watchdog may be prevented from resetting the system.
13226
13227        final String dropboxTag = processClass(process) + "_" + eventType;
13228        final DropBoxManager dbox = (DropBoxManager)
13229                mContext.getSystemService(Context.DROPBOX_SERVICE);
13230
13231        // Exit early if the dropbox isn't configured to accept this report type.
13232        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13233
13234        // Rate-limit how often we're willing to do the heavy lifting below to
13235        // collect and record logs; currently 5 logs per 10 second period.
13236        final long now = SystemClock.elapsedRealtime();
13237        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13238            mWtfClusterStart = now;
13239            mWtfClusterCount = 1;
13240        } else {
13241            if (mWtfClusterCount++ >= 5) return;
13242        }
13243
13244        final StringBuilder sb = new StringBuilder(1024);
13245        appendDropBoxProcessHeaders(process, processName, sb);
13246        if (process != null) {
13247            sb.append("Foreground: ")
13248                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13249                    .append("\n");
13250        }
13251        if (activity != null) {
13252            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13253        }
13254        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13255            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13256        }
13257        if (parent != null && parent != activity) {
13258            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13259        }
13260        if (subject != null) {
13261            sb.append("Subject: ").append(subject).append("\n");
13262        }
13263        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13264        if (Debug.isDebuggerConnected()) {
13265            sb.append("Debugger: Connected\n");
13266        }
13267        sb.append("\n");
13268
13269        // Do the rest in a worker thread to avoid blocking the caller on I/O
13270        // (After this point, we shouldn't access AMS internal data structures.)
13271        Thread worker = new Thread("Error dump: " + dropboxTag) {
13272            @Override
13273            public void run() {
13274                if (report != null) {
13275                    sb.append(report);
13276                }
13277                if (logFile != null) {
13278                    try {
13279                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13280                                    "\n\n[[TRUNCATED]]"));
13281                    } catch (IOException e) {
13282                        Slog.e(TAG, "Error reading " + logFile, e);
13283                    }
13284                }
13285                if (crashInfo != null && crashInfo.stackTrace != null) {
13286                    sb.append(crashInfo.stackTrace);
13287                }
13288
13289                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13290                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13291                if (lines > 0) {
13292                    sb.append("\n");
13293
13294                    // Merge several logcat streams, and take the last N lines
13295                    InputStreamReader input = null;
13296                    try {
13297                        java.lang.Process logcat = new ProcessBuilder(
13298                                "/system/bin/timeout", "-k", "15s", "10s",
13299                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13300                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13301                                        .redirectErrorStream(true).start();
13302
13303                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13304                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13305                        input = new InputStreamReader(logcat.getInputStream());
13306
13307                        int num;
13308                        char[] buf = new char[8192];
13309                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13310                    } catch (IOException e) {
13311                        Slog.e(TAG, "Error running logcat", e);
13312                    } finally {
13313                        if (input != null) try { input.close(); } catch (IOException e) {}
13314                    }
13315                }
13316
13317                dbox.addText(dropboxTag, sb.toString());
13318            }
13319        };
13320
13321        if (process == null) {
13322            // If process is null, we are being called from some internal code
13323            // and may be about to die -- run this synchronously.
13324            worker.run();
13325        } else {
13326            worker.start();
13327        }
13328    }
13329
13330    @Override
13331    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13332        enforceNotIsolatedCaller("getProcessesInErrorState");
13333        // assume our apps are happy - lazy create the list
13334        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13335
13336        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13337                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13338        int userId = UserHandle.getUserId(Binder.getCallingUid());
13339
13340        synchronized (this) {
13341
13342            // iterate across all processes
13343            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13344                ProcessRecord app = mLruProcesses.get(i);
13345                if (!allUsers && app.userId != userId) {
13346                    continue;
13347                }
13348                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13349                    // This one's in trouble, so we'll generate a report for it
13350                    // crashes are higher priority (in case there's a crash *and* an anr)
13351                    ActivityManager.ProcessErrorStateInfo report = null;
13352                    if (app.crashing) {
13353                        report = app.crashingReport;
13354                    } else if (app.notResponding) {
13355                        report = app.notRespondingReport;
13356                    }
13357
13358                    if (report != null) {
13359                        if (errList == null) {
13360                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13361                        }
13362                        errList.add(report);
13363                    } else {
13364                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13365                                " crashing = " + app.crashing +
13366                                " notResponding = " + app.notResponding);
13367                    }
13368                }
13369            }
13370        }
13371
13372        return errList;
13373    }
13374
13375    static int procStateToImportance(int procState, int memAdj,
13376            ActivityManager.RunningAppProcessInfo currApp) {
13377        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13378        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13379            currApp.lru = memAdj;
13380        } else {
13381            currApp.lru = 0;
13382        }
13383        return imp;
13384    }
13385
13386    private void fillInProcMemInfo(ProcessRecord app,
13387            ActivityManager.RunningAppProcessInfo outInfo) {
13388        outInfo.pid = app.pid;
13389        outInfo.uid = app.info.uid;
13390        if (mHeavyWeightProcess == app) {
13391            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13392        }
13393        if (app.persistent) {
13394            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13395        }
13396        if (app.activities.size() > 0) {
13397            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13398        }
13399        outInfo.lastTrimLevel = app.trimMemoryLevel;
13400        int adj = app.curAdj;
13401        int procState = app.curProcState;
13402        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13403        outInfo.importanceReasonCode = app.adjTypeCode;
13404        outInfo.processState = app.curProcState;
13405    }
13406
13407    @Override
13408    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13409        enforceNotIsolatedCaller("getRunningAppProcesses");
13410
13411        final int callingUid = Binder.getCallingUid();
13412
13413        // Lazy instantiation of list
13414        List<ActivityManager.RunningAppProcessInfo> runList = null;
13415        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13416                callingUid) == PackageManager.PERMISSION_GRANTED;
13417        final int userId = UserHandle.getUserId(callingUid);
13418        final boolean allUids = isGetTasksAllowed(
13419                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13420
13421        synchronized (this) {
13422            // Iterate across all processes
13423            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13424                ProcessRecord app = mLruProcesses.get(i);
13425                if ((!allUsers && app.userId != userId)
13426                        || (!allUids && app.uid != callingUid)) {
13427                    continue;
13428                }
13429                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13430                    // Generate process state info for running application
13431                    ActivityManager.RunningAppProcessInfo currApp =
13432                        new ActivityManager.RunningAppProcessInfo(app.processName,
13433                                app.pid, app.getPackageList());
13434                    fillInProcMemInfo(app, currApp);
13435                    if (app.adjSource instanceof ProcessRecord) {
13436                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13437                        currApp.importanceReasonImportance =
13438                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13439                                        app.adjSourceProcState);
13440                    } else if (app.adjSource instanceof ActivityRecord) {
13441                        ActivityRecord r = (ActivityRecord)app.adjSource;
13442                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13443                    }
13444                    if (app.adjTarget instanceof ComponentName) {
13445                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13446                    }
13447                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13448                    //        + " lru=" + currApp.lru);
13449                    if (runList == null) {
13450                        runList = new ArrayList<>();
13451                    }
13452                    runList.add(currApp);
13453                }
13454            }
13455        }
13456        return runList;
13457    }
13458
13459    @Override
13460    public List<ApplicationInfo> getRunningExternalApplications() {
13461        enforceNotIsolatedCaller("getRunningExternalApplications");
13462        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13463        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13464        if (runningApps != null && runningApps.size() > 0) {
13465            Set<String> extList = new HashSet<String>();
13466            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13467                if (app.pkgList != null) {
13468                    for (String pkg : app.pkgList) {
13469                        extList.add(pkg);
13470                    }
13471                }
13472            }
13473            IPackageManager pm = AppGlobals.getPackageManager();
13474            for (String pkg : extList) {
13475                try {
13476                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13477                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13478                        retList.add(info);
13479                    }
13480                } catch (RemoteException e) {
13481                }
13482            }
13483        }
13484        return retList;
13485    }
13486
13487    @Override
13488    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13489        enforceNotIsolatedCaller("getMyMemoryState");
13490        synchronized (this) {
13491            ProcessRecord proc;
13492            synchronized (mPidsSelfLocked) {
13493                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13494            }
13495            fillInProcMemInfo(proc, outInfo);
13496        }
13497    }
13498
13499    @Override
13500    public int getMemoryTrimLevel() {
13501        enforceNotIsolatedCaller("getMyMemoryState");
13502        synchronized (this) {
13503            return mLastMemoryLevel;
13504        }
13505    }
13506
13507    @Override
13508    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13509            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13510        (new ActivityManagerShellCommand(this, false)).exec(
13511                this, in, out, err, args, resultReceiver);
13512    }
13513
13514    @Override
13515    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13516        if (checkCallingPermission(android.Manifest.permission.DUMP)
13517                != PackageManager.PERMISSION_GRANTED) {
13518            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13519                    + Binder.getCallingPid()
13520                    + ", uid=" + Binder.getCallingUid()
13521                    + " without permission "
13522                    + android.Manifest.permission.DUMP);
13523            return;
13524        }
13525
13526        boolean dumpAll = false;
13527        boolean dumpClient = false;
13528        String dumpPackage = null;
13529
13530        int opti = 0;
13531        while (opti < args.length) {
13532            String opt = args[opti];
13533            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13534                break;
13535            }
13536            opti++;
13537            if ("-a".equals(opt)) {
13538                dumpAll = true;
13539            } else if ("-c".equals(opt)) {
13540                dumpClient = true;
13541            } else if ("-p".equals(opt)) {
13542                if (opti < args.length) {
13543                    dumpPackage = args[opti];
13544                    opti++;
13545                } else {
13546                    pw.println("Error: -p option requires package argument");
13547                    return;
13548                }
13549                dumpClient = true;
13550            } else if ("-h".equals(opt)) {
13551                ActivityManagerShellCommand.dumpHelp(pw, true);
13552                return;
13553            } else {
13554                pw.println("Unknown argument: " + opt + "; use -h for help");
13555            }
13556        }
13557
13558        long origId = Binder.clearCallingIdentity();
13559        boolean more = false;
13560        // Is the caller requesting to dump a particular piece of data?
13561        if (opti < args.length) {
13562            String cmd = args[opti];
13563            opti++;
13564            if ("activities".equals(cmd) || "a".equals(cmd)) {
13565                synchronized (this) {
13566                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13567                }
13568            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13569                synchronized (this) {
13570                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13571                }
13572            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13573                String[] newArgs;
13574                String name;
13575                if (opti >= args.length) {
13576                    name = null;
13577                    newArgs = EMPTY_STRING_ARRAY;
13578                } else {
13579                    dumpPackage = args[opti];
13580                    opti++;
13581                    newArgs = new String[args.length - opti];
13582                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13583                            args.length - opti);
13584                }
13585                synchronized (this) {
13586                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13587                }
13588            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13589                String[] newArgs;
13590                String name;
13591                if (opti >= args.length) {
13592                    name = null;
13593                    newArgs = EMPTY_STRING_ARRAY;
13594                } else {
13595                    dumpPackage = args[opti];
13596                    opti++;
13597                    newArgs = new String[args.length - opti];
13598                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13599                            args.length - opti);
13600                }
13601                synchronized (this) {
13602                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13603                }
13604            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13605                String[] newArgs;
13606                String name;
13607                if (opti >= args.length) {
13608                    name = null;
13609                    newArgs = EMPTY_STRING_ARRAY;
13610                } else {
13611                    dumpPackage = args[opti];
13612                    opti++;
13613                    newArgs = new String[args.length - opti];
13614                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13615                            args.length - opti);
13616                }
13617                synchronized (this) {
13618                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13619                }
13620            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13621                synchronized (this) {
13622                    dumpOomLocked(fd, pw, args, opti, true);
13623                }
13624            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13625                synchronized (this) {
13626                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13627                }
13628            } else if ("provider".equals(cmd)) {
13629                String[] newArgs;
13630                String name;
13631                if (opti >= args.length) {
13632                    name = null;
13633                    newArgs = EMPTY_STRING_ARRAY;
13634                } else {
13635                    name = args[opti];
13636                    opti++;
13637                    newArgs = new String[args.length - opti];
13638                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13639                }
13640                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13641                    pw.println("No providers match: " + name);
13642                    pw.println("Use -h for help.");
13643                }
13644            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13645                synchronized (this) {
13646                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13647                }
13648            } else if ("service".equals(cmd)) {
13649                String[] newArgs;
13650                String name;
13651                if (opti >= args.length) {
13652                    name = null;
13653                    newArgs = EMPTY_STRING_ARRAY;
13654                } else {
13655                    name = args[opti];
13656                    opti++;
13657                    newArgs = new String[args.length - opti];
13658                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13659                            args.length - opti);
13660                }
13661                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13662                    pw.println("No services match: " + name);
13663                    pw.println("Use -h for help.");
13664                }
13665            } else if ("package".equals(cmd)) {
13666                String[] newArgs;
13667                if (opti >= args.length) {
13668                    pw.println("package: no package name specified");
13669                    pw.println("Use -h for help.");
13670                } else {
13671                    dumpPackage = args[opti];
13672                    opti++;
13673                    newArgs = new String[args.length - opti];
13674                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13675                            args.length - opti);
13676                    args = newArgs;
13677                    opti = 0;
13678                    more = true;
13679                }
13680            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13681                synchronized (this) {
13682                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13683                }
13684            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13685                synchronized (this) {
13686                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13687                }
13688            } else if ("locks".equals(cmd)) {
13689                LockGuard.dump(fd, pw, args);
13690            } else {
13691                // Dumping a single activity?
13692                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13693                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13694                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13695                    if (res < 0) {
13696                        pw.println("Bad activity command, or no activities match: " + cmd);
13697                        pw.println("Use -h for help.");
13698                    }
13699                }
13700            }
13701            if (!more) {
13702                Binder.restoreCallingIdentity(origId);
13703                return;
13704            }
13705        }
13706
13707        // No piece of data specified, dump everything.
13708        synchronized (this) {
13709            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13710            pw.println();
13711            if (dumpAll) {
13712                pw.println("-------------------------------------------------------------------------------");
13713            }
13714            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13715            pw.println();
13716            if (dumpAll) {
13717                pw.println("-------------------------------------------------------------------------------");
13718            }
13719            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13720            pw.println();
13721            if (dumpAll) {
13722                pw.println("-------------------------------------------------------------------------------");
13723            }
13724            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13725            pw.println();
13726            if (dumpAll) {
13727                pw.println("-------------------------------------------------------------------------------");
13728            }
13729            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13730            pw.println();
13731            if (dumpAll) {
13732                pw.println("-------------------------------------------------------------------------------");
13733            }
13734            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13735            pw.println();
13736            if (dumpAll) {
13737                pw.println("-------------------------------------------------------------------------------");
13738            }
13739            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13740            if (mAssociations.size() > 0) {
13741                pw.println();
13742                if (dumpAll) {
13743                    pw.println("-------------------------------------------------------------------------------");
13744                }
13745                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13746            }
13747            pw.println();
13748            if (dumpAll) {
13749                pw.println("-------------------------------------------------------------------------------");
13750            }
13751            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13752        }
13753        Binder.restoreCallingIdentity(origId);
13754    }
13755
13756    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13757            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13758        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13759
13760        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13761                dumpPackage);
13762        boolean needSep = printedAnything;
13763
13764        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13765                dumpPackage, needSep, "  mFocusedActivity: ");
13766        if (printed) {
13767            printedAnything = true;
13768            needSep = false;
13769        }
13770
13771        if (dumpPackage == null) {
13772            if (needSep) {
13773                pw.println();
13774            }
13775            needSep = true;
13776            printedAnything = true;
13777            mStackSupervisor.dump(pw, "  ");
13778        }
13779
13780        if (!printedAnything) {
13781            pw.println("  (nothing)");
13782        }
13783    }
13784
13785    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13786            int opti, boolean dumpAll, String dumpPackage) {
13787        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13788
13789        boolean printedAnything = false;
13790
13791        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13792            boolean printedHeader = false;
13793
13794            final int N = mRecentTasks.size();
13795            for (int i=0; i<N; i++) {
13796                TaskRecord tr = mRecentTasks.get(i);
13797                if (dumpPackage != null) {
13798                    if (tr.realActivity == null ||
13799                            !dumpPackage.equals(tr.realActivity)) {
13800                        continue;
13801                    }
13802                }
13803                if (!printedHeader) {
13804                    pw.println("  Recent tasks:");
13805                    printedHeader = true;
13806                    printedAnything = true;
13807                }
13808                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13809                        pw.println(tr);
13810                if (dumpAll) {
13811                    mRecentTasks.get(i).dump(pw, "    ");
13812                }
13813            }
13814        }
13815
13816        if (!printedAnything) {
13817            pw.println("  (nothing)");
13818        }
13819    }
13820
13821    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13822            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13823        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13824
13825        int dumpUid = 0;
13826        if (dumpPackage != null) {
13827            IPackageManager pm = AppGlobals.getPackageManager();
13828            try {
13829                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13830            } catch (RemoteException e) {
13831            }
13832        }
13833
13834        boolean printedAnything = false;
13835
13836        final long now = SystemClock.uptimeMillis();
13837
13838        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13839            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13840                    = mAssociations.valueAt(i1);
13841            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13842                SparseArray<ArrayMap<String, Association>> sourceUids
13843                        = targetComponents.valueAt(i2);
13844                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13845                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13846                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13847                        Association ass = sourceProcesses.valueAt(i4);
13848                        if (dumpPackage != null) {
13849                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13850                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13851                                continue;
13852                            }
13853                        }
13854                        printedAnything = true;
13855                        pw.print("  ");
13856                        pw.print(ass.mTargetProcess);
13857                        pw.print("/");
13858                        UserHandle.formatUid(pw, ass.mTargetUid);
13859                        pw.print(" <- ");
13860                        pw.print(ass.mSourceProcess);
13861                        pw.print("/");
13862                        UserHandle.formatUid(pw, ass.mSourceUid);
13863                        pw.println();
13864                        pw.print("    via ");
13865                        pw.print(ass.mTargetComponent.flattenToShortString());
13866                        pw.println();
13867                        pw.print("    ");
13868                        long dur = ass.mTime;
13869                        if (ass.mNesting > 0) {
13870                            dur += now - ass.mStartTime;
13871                        }
13872                        TimeUtils.formatDuration(dur, pw);
13873                        pw.print(" (");
13874                        pw.print(ass.mCount);
13875                        pw.print(" times)");
13876                        pw.print("  ");
13877                        for (int i=0; i<ass.mStateTimes.length; i++) {
13878                            long amt = ass.mStateTimes[i];
13879                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13880                                amt += now - ass.mLastStateUptime;
13881                            }
13882                            if (amt != 0) {
13883                                pw.print(" ");
13884                                pw.print(ProcessList.makeProcStateString(
13885                                            i + ActivityManager.MIN_PROCESS_STATE));
13886                                pw.print("=");
13887                                TimeUtils.formatDuration(amt, pw);
13888                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13889                                    pw.print("*");
13890                                }
13891                            }
13892                        }
13893                        pw.println();
13894                        if (ass.mNesting > 0) {
13895                            pw.print("    Currently active: ");
13896                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13897                            pw.println();
13898                        }
13899                    }
13900                }
13901            }
13902
13903        }
13904
13905        if (!printedAnything) {
13906            pw.println("  (nothing)");
13907        }
13908    }
13909
13910    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13911            String header, boolean needSep) {
13912        boolean printed = false;
13913        int whichAppId = -1;
13914        if (dumpPackage != null) {
13915            try {
13916                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13917                        dumpPackage, 0);
13918                whichAppId = UserHandle.getAppId(info.uid);
13919            } catch (NameNotFoundException e) {
13920                e.printStackTrace();
13921            }
13922        }
13923        for (int i=0; i<uids.size(); i++) {
13924            UidRecord uidRec = uids.valueAt(i);
13925            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13926                continue;
13927            }
13928            if (!printed) {
13929                printed = true;
13930                if (needSep) {
13931                    pw.println();
13932                }
13933                pw.print("  ");
13934                pw.println(header);
13935                needSep = true;
13936            }
13937            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13938            pw.print(": "); pw.println(uidRec);
13939        }
13940        return printed;
13941    }
13942
13943    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13944            int opti, boolean dumpAll, String dumpPackage) {
13945        boolean needSep = false;
13946        boolean printedAnything = false;
13947        int numPers = 0;
13948
13949        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13950
13951        if (dumpAll) {
13952            final int NP = mProcessNames.getMap().size();
13953            for (int ip=0; ip<NP; ip++) {
13954                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13955                final int NA = procs.size();
13956                for (int ia=0; ia<NA; ia++) {
13957                    ProcessRecord r = procs.valueAt(ia);
13958                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13959                        continue;
13960                    }
13961                    if (!needSep) {
13962                        pw.println("  All known processes:");
13963                        needSep = true;
13964                        printedAnything = true;
13965                    }
13966                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13967                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13968                        pw.print(" "); pw.println(r);
13969                    r.dump(pw, "    ");
13970                    if (r.persistent) {
13971                        numPers++;
13972                    }
13973                }
13974            }
13975        }
13976
13977        if (mIsolatedProcesses.size() > 0) {
13978            boolean printed = false;
13979            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13980                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13981                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13982                    continue;
13983                }
13984                if (!printed) {
13985                    if (needSep) {
13986                        pw.println();
13987                    }
13988                    pw.println("  Isolated process list (sorted by uid):");
13989                    printedAnything = true;
13990                    printed = true;
13991                    needSep = true;
13992                }
13993                pw.println(String.format("%sIsolated #%2d: %s",
13994                        "    ", i, r.toString()));
13995            }
13996        }
13997
13998        if (mActiveUids.size() > 0) {
13999            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14000                printedAnything = needSep = true;
14001            }
14002        }
14003        if (mValidateUids.size() > 0) {
14004            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14005                printedAnything = needSep = true;
14006            }
14007        }
14008
14009        if (mLruProcesses.size() > 0) {
14010            if (needSep) {
14011                pw.println();
14012            }
14013            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14014                    pw.print(" total, non-act at ");
14015                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14016                    pw.print(", non-svc at ");
14017                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14018                    pw.println("):");
14019            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14020            needSep = true;
14021            printedAnything = true;
14022        }
14023
14024        if (dumpAll || dumpPackage != null) {
14025            synchronized (mPidsSelfLocked) {
14026                boolean printed = false;
14027                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14028                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14029                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14030                        continue;
14031                    }
14032                    if (!printed) {
14033                        if (needSep) pw.println();
14034                        needSep = true;
14035                        pw.println("  PID mappings:");
14036                        printed = true;
14037                        printedAnything = true;
14038                    }
14039                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14040                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14041                }
14042            }
14043        }
14044
14045        if (mForegroundProcesses.size() > 0) {
14046            synchronized (mPidsSelfLocked) {
14047                boolean printed = false;
14048                for (int i=0; i<mForegroundProcesses.size(); i++) {
14049                    ProcessRecord r = mPidsSelfLocked.get(
14050                            mForegroundProcesses.valueAt(i).pid);
14051                    if (dumpPackage != null && (r == null
14052                            || !r.pkgList.containsKey(dumpPackage))) {
14053                        continue;
14054                    }
14055                    if (!printed) {
14056                        if (needSep) pw.println();
14057                        needSep = true;
14058                        pw.println("  Foreground Processes:");
14059                        printed = true;
14060                        printedAnything = true;
14061                    }
14062                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14063                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14064                }
14065            }
14066        }
14067
14068        if (mPersistentStartingProcesses.size() > 0) {
14069            if (needSep) pw.println();
14070            needSep = true;
14071            printedAnything = true;
14072            pw.println("  Persisent processes that are starting:");
14073            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14074                    "Starting Norm", "Restarting PERS", dumpPackage);
14075        }
14076
14077        if (mRemovedProcesses.size() > 0) {
14078            if (needSep) pw.println();
14079            needSep = true;
14080            printedAnything = true;
14081            pw.println("  Processes that are being removed:");
14082            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14083                    "Removed Norm", "Removed PERS", dumpPackage);
14084        }
14085
14086        if (mProcessesOnHold.size() > 0) {
14087            if (needSep) pw.println();
14088            needSep = true;
14089            printedAnything = true;
14090            pw.println("  Processes that are on old until the system is ready:");
14091            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14092                    "OnHold Norm", "OnHold PERS", dumpPackage);
14093        }
14094
14095        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14096
14097        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14098        if (needSep) {
14099            printedAnything = true;
14100        }
14101
14102        if (dumpPackage == null) {
14103            pw.println();
14104            needSep = false;
14105            mUserController.dump(pw, dumpAll);
14106        }
14107        if (mHomeProcess != null && (dumpPackage == null
14108                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14109            if (needSep) {
14110                pw.println();
14111                needSep = false;
14112            }
14113            pw.println("  mHomeProcess: " + mHomeProcess);
14114        }
14115        if (mPreviousProcess != null && (dumpPackage == null
14116                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14117            if (needSep) {
14118                pw.println();
14119                needSep = false;
14120            }
14121            pw.println("  mPreviousProcess: " + mPreviousProcess);
14122        }
14123        if (dumpAll) {
14124            StringBuilder sb = new StringBuilder(128);
14125            sb.append("  mPreviousProcessVisibleTime: ");
14126            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14127            pw.println(sb);
14128        }
14129        if (mHeavyWeightProcess != null && (dumpPackage == null
14130                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14131            if (needSep) {
14132                pw.println();
14133                needSep = false;
14134            }
14135            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14136        }
14137        if (dumpPackage == null) {
14138            pw.println("  mConfiguration: " + mConfiguration);
14139        }
14140        if (dumpAll) {
14141            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14142            if (mCompatModePackages.getPackages().size() > 0) {
14143                boolean printed = false;
14144                for (Map.Entry<String, Integer> entry
14145                        : mCompatModePackages.getPackages().entrySet()) {
14146                    String pkg = entry.getKey();
14147                    int mode = entry.getValue();
14148                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14149                        continue;
14150                    }
14151                    if (!printed) {
14152                        pw.println("  mScreenCompatPackages:");
14153                        printed = true;
14154                    }
14155                    pw.print("    "); pw.print(pkg); pw.print(": ");
14156                            pw.print(mode); pw.println();
14157                }
14158            }
14159        }
14160        if (dumpPackage == null) {
14161            pw.println("  mWakefulness="
14162                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14163            pw.println("  mSleepTokens=" + mSleepTokens);
14164            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14165                    + lockScreenShownToString());
14166            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14167            if (mRunningVoice != null) {
14168                pw.println("  mRunningVoice=" + mRunningVoice);
14169                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14170            }
14171        }
14172        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14173                || mOrigWaitForDebugger) {
14174            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14175                    || dumpPackage.equals(mOrigDebugApp)) {
14176                if (needSep) {
14177                    pw.println();
14178                    needSep = false;
14179                }
14180                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14181                        + " mDebugTransient=" + mDebugTransient
14182                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14183            }
14184        }
14185        if (mCurAppTimeTracker != null) {
14186            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14187        }
14188        if (mMemWatchProcesses.getMap().size() > 0) {
14189            pw.println("  Mem watch processes:");
14190            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14191                    = mMemWatchProcesses.getMap();
14192            for (int i=0; i<procs.size(); i++) {
14193                final String proc = procs.keyAt(i);
14194                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14195                for (int j=0; j<uids.size(); j++) {
14196                    if (needSep) {
14197                        pw.println();
14198                        needSep = false;
14199                    }
14200                    StringBuilder sb = new StringBuilder();
14201                    sb.append("    ").append(proc).append('/');
14202                    UserHandle.formatUid(sb, uids.keyAt(j));
14203                    Pair<Long, String> val = uids.valueAt(j);
14204                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14205                    if (val.second != null) {
14206                        sb.append(", report to ").append(val.second);
14207                    }
14208                    pw.println(sb.toString());
14209                }
14210            }
14211            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14212            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14213            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14214                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14215        }
14216        if (mTrackAllocationApp != null) {
14217            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14218                if (needSep) {
14219                    pw.println();
14220                    needSep = false;
14221                }
14222                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14223            }
14224        }
14225        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14226                || mProfileFd != null) {
14227            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14228                if (needSep) {
14229                    pw.println();
14230                    needSep = false;
14231                }
14232                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14233                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14234                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14235                        + mAutoStopProfiler);
14236                pw.println("  mProfileType=" + mProfileType);
14237            }
14238        }
14239        if (mNativeDebuggingApp != null) {
14240            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14241                if (needSep) {
14242                    pw.println();
14243                    needSep = false;
14244                }
14245                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14246            }
14247        }
14248        if (dumpPackage == null) {
14249            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14250                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14251                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14252            }
14253            if (mController != null) {
14254                pw.println("  mController=" + mController
14255                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14256            }
14257            if (dumpAll) {
14258                pw.println("  Total persistent processes: " + numPers);
14259                pw.println("  mProcessesReady=" + mProcessesReady
14260                        + " mSystemReady=" + mSystemReady
14261                        + " mBooted=" + mBooted
14262                        + " mFactoryTest=" + mFactoryTest);
14263                pw.println("  mBooting=" + mBooting
14264                        + " mCallFinishBooting=" + mCallFinishBooting
14265                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14266                pw.print("  mLastPowerCheckRealtime=");
14267                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14268                        pw.println("");
14269                pw.print("  mLastPowerCheckUptime=");
14270                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14271                        pw.println("");
14272                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14273                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14274                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14275                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14276                        + " (" + mLruProcesses.size() + " total)"
14277                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14278                        + " mNumServiceProcs=" + mNumServiceProcs
14279                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14280                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14281                        + " mLastMemoryLevel=" + mLastMemoryLevel
14282                        + " mLastNumProcesses=" + mLastNumProcesses);
14283                long now = SystemClock.uptimeMillis();
14284                pw.print("  mLastIdleTime=");
14285                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14286                        pw.print(" mLowRamSinceLastIdle=");
14287                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14288                        pw.println();
14289            }
14290        }
14291
14292        if (!printedAnything) {
14293            pw.println("  (nothing)");
14294        }
14295    }
14296
14297    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14298            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14299        if (mProcessesToGc.size() > 0) {
14300            boolean printed = false;
14301            long now = SystemClock.uptimeMillis();
14302            for (int i=0; i<mProcessesToGc.size(); i++) {
14303                ProcessRecord proc = mProcessesToGc.get(i);
14304                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14305                    continue;
14306                }
14307                if (!printed) {
14308                    if (needSep) pw.println();
14309                    needSep = true;
14310                    pw.println("  Processes that are waiting to GC:");
14311                    printed = true;
14312                }
14313                pw.print("    Process "); pw.println(proc);
14314                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14315                        pw.print(", last gced=");
14316                        pw.print(now-proc.lastRequestedGc);
14317                        pw.print(" ms ago, last lowMem=");
14318                        pw.print(now-proc.lastLowMemory);
14319                        pw.println(" ms ago");
14320
14321            }
14322        }
14323        return needSep;
14324    }
14325
14326    void printOomLevel(PrintWriter pw, String name, int adj) {
14327        pw.print("    ");
14328        if (adj >= 0) {
14329            pw.print(' ');
14330            if (adj < 10) pw.print(' ');
14331        } else {
14332            if (adj > -10) pw.print(' ');
14333        }
14334        pw.print(adj);
14335        pw.print(": ");
14336        pw.print(name);
14337        pw.print(" (");
14338        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14339        pw.println(")");
14340    }
14341
14342    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14343            int opti, boolean dumpAll) {
14344        boolean needSep = false;
14345
14346        if (mLruProcesses.size() > 0) {
14347            if (needSep) pw.println();
14348            needSep = true;
14349            pw.println("  OOM levels:");
14350            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14351            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14352            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14353            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14354            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14355            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14356            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14357            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14358            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14359            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14360            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14361            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14362            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14363            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14364
14365            if (needSep) pw.println();
14366            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14367                    pw.print(" total, non-act at ");
14368                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14369                    pw.print(", non-svc at ");
14370                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14371                    pw.println("):");
14372            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14373            needSep = true;
14374        }
14375
14376        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14377
14378        pw.println();
14379        pw.println("  mHomeProcess: " + mHomeProcess);
14380        pw.println("  mPreviousProcess: " + mPreviousProcess);
14381        if (mHeavyWeightProcess != null) {
14382            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14383        }
14384
14385        return true;
14386    }
14387
14388    /**
14389     * There are three ways to call this:
14390     *  - no provider specified: dump all the providers
14391     *  - a flattened component name that matched an existing provider was specified as the
14392     *    first arg: dump that one provider
14393     *  - the first arg isn't the flattened component name of an existing provider:
14394     *    dump all providers whose component contains the first arg as a substring
14395     */
14396    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14397            int opti, boolean dumpAll) {
14398        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14399    }
14400
14401    static class ItemMatcher {
14402        ArrayList<ComponentName> components;
14403        ArrayList<String> strings;
14404        ArrayList<Integer> objects;
14405        boolean all;
14406
14407        ItemMatcher() {
14408            all = true;
14409        }
14410
14411        void build(String name) {
14412            ComponentName componentName = ComponentName.unflattenFromString(name);
14413            if (componentName != null) {
14414                if (components == null) {
14415                    components = new ArrayList<ComponentName>();
14416                }
14417                components.add(componentName);
14418                all = false;
14419            } else {
14420                int objectId = 0;
14421                // Not a '/' separated full component name; maybe an object ID?
14422                try {
14423                    objectId = Integer.parseInt(name, 16);
14424                    if (objects == null) {
14425                        objects = new ArrayList<Integer>();
14426                    }
14427                    objects.add(objectId);
14428                    all = false;
14429                } catch (RuntimeException e) {
14430                    // Not an integer; just do string match.
14431                    if (strings == null) {
14432                        strings = new ArrayList<String>();
14433                    }
14434                    strings.add(name);
14435                    all = false;
14436                }
14437            }
14438        }
14439
14440        int build(String[] args, int opti) {
14441            for (; opti<args.length; opti++) {
14442                String name = args[opti];
14443                if ("--".equals(name)) {
14444                    return opti+1;
14445                }
14446                build(name);
14447            }
14448            return opti;
14449        }
14450
14451        boolean match(Object object, ComponentName comp) {
14452            if (all) {
14453                return true;
14454            }
14455            if (components != null) {
14456                for (int i=0; i<components.size(); i++) {
14457                    if (components.get(i).equals(comp)) {
14458                        return true;
14459                    }
14460                }
14461            }
14462            if (objects != null) {
14463                for (int i=0; i<objects.size(); i++) {
14464                    if (System.identityHashCode(object) == objects.get(i)) {
14465                        return true;
14466                    }
14467                }
14468            }
14469            if (strings != null) {
14470                String flat = comp.flattenToString();
14471                for (int i=0; i<strings.size(); i++) {
14472                    if (flat.contains(strings.get(i))) {
14473                        return true;
14474                    }
14475                }
14476            }
14477            return false;
14478        }
14479    }
14480
14481    /**
14482     * There are three things that cmd can be:
14483     *  - a flattened component name that matches an existing activity
14484     *  - the cmd arg isn't the flattened component name of an existing activity:
14485     *    dump all activity whose component contains the cmd as a substring
14486     *  - A hex number of the ActivityRecord object instance.
14487     */
14488    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14489            int opti, boolean dumpAll) {
14490        ArrayList<ActivityRecord> activities;
14491
14492        synchronized (this) {
14493            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14494        }
14495
14496        if (activities.size() <= 0) {
14497            return false;
14498        }
14499
14500        String[] newArgs = new String[args.length - opti];
14501        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14502
14503        TaskRecord lastTask = null;
14504        boolean needSep = false;
14505        for (int i=activities.size()-1; i>=0; i--) {
14506            ActivityRecord r = activities.get(i);
14507            if (needSep) {
14508                pw.println();
14509            }
14510            needSep = true;
14511            synchronized (this) {
14512                if (lastTask != r.task) {
14513                    lastTask = r.task;
14514                    pw.print("TASK "); pw.print(lastTask.affinity);
14515                            pw.print(" id="); pw.println(lastTask.taskId);
14516                    if (dumpAll) {
14517                        lastTask.dump(pw, "  ");
14518                    }
14519                }
14520            }
14521            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14522        }
14523        return true;
14524    }
14525
14526    /**
14527     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14528     * there is a thread associated with the activity.
14529     */
14530    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14531            final ActivityRecord r, String[] args, boolean dumpAll) {
14532        String innerPrefix = prefix + "  ";
14533        synchronized (this) {
14534            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14535                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14536                    pw.print(" pid=");
14537                    if (r.app != null) pw.println(r.app.pid);
14538                    else pw.println("(not running)");
14539            if (dumpAll) {
14540                r.dump(pw, innerPrefix);
14541            }
14542        }
14543        if (r.app != null && r.app.thread != null) {
14544            // flush anything that is already in the PrintWriter since the thread is going
14545            // to write to the file descriptor directly
14546            pw.flush();
14547            try {
14548                TransferPipe tp = new TransferPipe();
14549                try {
14550                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14551                            r.appToken, innerPrefix, args);
14552                    tp.go(fd);
14553                } finally {
14554                    tp.kill();
14555                }
14556            } catch (IOException e) {
14557                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14558            } catch (RemoteException e) {
14559                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14560            }
14561        }
14562    }
14563
14564    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14565            int opti, boolean dumpAll, String dumpPackage) {
14566        boolean needSep = false;
14567        boolean onlyHistory = false;
14568        boolean printedAnything = false;
14569
14570        if ("history".equals(dumpPackage)) {
14571            if (opti < args.length && "-s".equals(args[opti])) {
14572                dumpAll = false;
14573            }
14574            onlyHistory = true;
14575            dumpPackage = null;
14576        }
14577
14578        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14579        if (!onlyHistory && dumpAll) {
14580            if (mRegisteredReceivers.size() > 0) {
14581                boolean printed = false;
14582                Iterator it = mRegisteredReceivers.values().iterator();
14583                while (it.hasNext()) {
14584                    ReceiverList r = (ReceiverList)it.next();
14585                    if (dumpPackage != null && (r.app == null ||
14586                            !dumpPackage.equals(r.app.info.packageName))) {
14587                        continue;
14588                    }
14589                    if (!printed) {
14590                        pw.println("  Registered Receivers:");
14591                        needSep = true;
14592                        printed = true;
14593                        printedAnything = true;
14594                    }
14595                    pw.print("  * "); pw.println(r);
14596                    r.dump(pw, "    ");
14597                }
14598            }
14599
14600            if (mReceiverResolver.dump(pw, needSep ?
14601                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14602                    "    ", dumpPackage, false, false)) {
14603                needSep = true;
14604                printedAnything = true;
14605            }
14606        }
14607
14608        for (BroadcastQueue q : mBroadcastQueues) {
14609            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14610            printedAnything |= needSep;
14611        }
14612
14613        needSep = true;
14614
14615        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14616            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14617                if (needSep) {
14618                    pw.println();
14619                }
14620                needSep = true;
14621                printedAnything = true;
14622                pw.print("  Sticky broadcasts for user ");
14623                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14624                StringBuilder sb = new StringBuilder(128);
14625                for (Map.Entry<String, ArrayList<Intent>> ent
14626                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14627                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14628                    if (dumpAll) {
14629                        pw.println(":");
14630                        ArrayList<Intent> intents = ent.getValue();
14631                        final int N = intents.size();
14632                        for (int i=0; i<N; i++) {
14633                            sb.setLength(0);
14634                            sb.append("    Intent: ");
14635                            intents.get(i).toShortString(sb, false, true, false, false);
14636                            pw.println(sb.toString());
14637                            Bundle bundle = intents.get(i).getExtras();
14638                            if (bundle != null) {
14639                                pw.print("      ");
14640                                pw.println(bundle.toString());
14641                            }
14642                        }
14643                    } else {
14644                        pw.println("");
14645                    }
14646                }
14647            }
14648        }
14649
14650        if (!onlyHistory && dumpAll) {
14651            pw.println();
14652            for (BroadcastQueue queue : mBroadcastQueues) {
14653                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14654                        + queue.mBroadcastsScheduled);
14655            }
14656            pw.println("  mHandler:");
14657            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14658            needSep = true;
14659            printedAnything = true;
14660        }
14661
14662        if (!printedAnything) {
14663            pw.println("  (nothing)");
14664        }
14665    }
14666
14667    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14668            int opti, boolean dumpAll, String dumpPackage) {
14669        boolean needSep;
14670        boolean printedAnything = false;
14671
14672        ItemMatcher matcher = new ItemMatcher();
14673        matcher.build(args, opti);
14674
14675        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14676
14677        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14678        printedAnything |= needSep;
14679
14680        if (mLaunchingProviders.size() > 0) {
14681            boolean printed = false;
14682            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14683                ContentProviderRecord r = mLaunchingProviders.get(i);
14684                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14685                    continue;
14686                }
14687                if (!printed) {
14688                    if (needSep) pw.println();
14689                    needSep = true;
14690                    pw.println("  Launching content providers:");
14691                    printed = true;
14692                    printedAnything = true;
14693                }
14694                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14695                        pw.println(r);
14696            }
14697        }
14698
14699        if (!printedAnything) {
14700            pw.println("  (nothing)");
14701        }
14702    }
14703
14704    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14705            int opti, boolean dumpAll, String dumpPackage) {
14706        boolean needSep = false;
14707        boolean printedAnything = false;
14708
14709        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14710
14711        if (mGrantedUriPermissions.size() > 0) {
14712            boolean printed = false;
14713            int dumpUid = -2;
14714            if (dumpPackage != null) {
14715                try {
14716                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14717                            MATCH_UNINSTALLED_PACKAGES, 0);
14718                } catch (NameNotFoundException e) {
14719                    dumpUid = -1;
14720                }
14721            }
14722            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14723                int uid = mGrantedUriPermissions.keyAt(i);
14724                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14725                    continue;
14726                }
14727                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14728                if (!printed) {
14729                    if (needSep) pw.println();
14730                    needSep = true;
14731                    pw.println("  Granted Uri Permissions:");
14732                    printed = true;
14733                    printedAnything = true;
14734                }
14735                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14736                for (UriPermission perm : perms.values()) {
14737                    pw.print("    "); pw.println(perm);
14738                    if (dumpAll) {
14739                        perm.dump(pw, "      ");
14740                    }
14741                }
14742            }
14743        }
14744
14745        if (!printedAnything) {
14746            pw.println("  (nothing)");
14747        }
14748    }
14749
14750    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14751            int opti, boolean dumpAll, String dumpPackage) {
14752        boolean printed = false;
14753
14754        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14755
14756        if (mIntentSenderRecords.size() > 0) {
14757            Iterator<WeakReference<PendingIntentRecord>> it
14758                    = mIntentSenderRecords.values().iterator();
14759            while (it.hasNext()) {
14760                WeakReference<PendingIntentRecord> ref = it.next();
14761                PendingIntentRecord rec = ref != null ? ref.get(): null;
14762                if (dumpPackage != null && (rec == null
14763                        || !dumpPackage.equals(rec.key.packageName))) {
14764                    continue;
14765                }
14766                printed = true;
14767                if (rec != null) {
14768                    pw.print("  * "); pw.println(rec);
14769                    if (dumpAll) {
14770                        rec.dump(pw, "    ");
14771                    }
14772                } else {
14773                    pw.print("  * "); pw.println(ref);
14774                }
14775            }
14776        }
14777
14778        if (!printed) {
14779            pw.println("  (nothing)");
14780        }
14781    }
14782
14783    private static final int dumpProcessList(PrintWriter pw,
14784            ActivityManagerService service, List list,
14785            String prefix, String normalLabel, String persistentLabel,
14786            String dumpPackage) {
14787        int numPers = 0;
14788        final int N = list.size()-1;
14789        for (int i=N; i>=0; i--) {
14790            ProcessRecord r = (ProcessRecord)list.get(i);
14791            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14792                continue;
14793            }
14794            pw.println(String.format("%s%s #%2d: %s",
14795                    prefix, (r.persistent ? persistentLabel : normalLabel),
14796                    i, r.toString()));
14797            if (r.persistent) {
14798                numPers++;
14799            }
14800        }
14801        return numPers;
14802    }
14803
14804    private static final boolean dumpProcessOomList(PrintWriter pw,
14805            ActivityManagerService service, List<ProcessRecord> origList,
14806            String prefix, String normalLabel, String persistentLabel,
14807            boolean inclDetails, String dumpPackage) {
14808
14809        ArrayList<Pair<ProcessRecord, Integer>> list
14810                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14811        for (int i=0; i<origList.size(); i++) {
14812            ProcessRecord r = origList.get(i);
14813            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14814                continue;
14815            }
14816            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14817        }
14818
14819        if (list.size() <= 0) {
14820            return false;
14821        }
14822
14823        Comparator<Pair<ProcessRecord, Integer>> comparator
14824                = new Comparator<Pair<ProcessRecord, Integer>>() {
14825            @Override
14826            public int compare(Pair<ProcessRecord, Integer> object1,
14827                    Pair<ProcessRecord, Integer> object2) {
14828                if (object1.first.setAdj != object2.first.setAdj) {
14829                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14830                }
14831                if (object1.first.setProcState != object2.first.setProcState) {
14832                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14833                }
14834                if (object1.second.intValue() != object2.second.intValue()) {
14835                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14836                }
14837                return 0;
14838            }
14839        };
14840
14841        Collections.sort(list, comparator);
14842
14843        final long curRealtime = SystemClock.elapsedRealtime();
14844        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14845        final long curUptime = SystemClock.uptimeMillis();
14846        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14847
14848        for (int i=list.size()-1; i>=0; i--) {
14849            ProcessRecord r = list.get(i).first;
14850            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14851            char schedGroup;
14852            switch (r.setSchedGroup) {
14853                case ProcessList.SCHED_GROUP_BACKGROUND:
14854                    schedGroup = 'B';
14855                    break;
14856                case ProcessList.SCHED_GROUP_DEFAULT:
14857                    schedGroup = 'F';
14858                    break;
14859                case ProcessList.SCHED_GROUP_TOP_APP:
14860                    schedGroup = 'T';
14861                    break;
14862                default:
14863                    schedGroup = '?';
14864                    break;
14865            }
14866            char foreground;
14867            if (r.foregroundActivities) {
14868                foreground = 'A';
14869            } else if (r.foregroundServices) {
14870                foreground = 'S';
14871            } else {
14872                foreground = ' ';
14873            }
14874            String procState = ProcessList.makeProcStateString(r.curProcState);
14875            pw.print(prefix);
14876            pw.print(r.persistent ? persistentLabel : normalLabel);
14877            pw.print(" #");
14878            int num = (origList.size()-1)-list.get(i).second;
14879            if (num < 10) pw.print(' ');
14880            pw.print(num);
14881            pw.print(": ");
14882            pw.print(oomAdj);
14883            pw.print(' ');
14884            pw.print(schedGroup);
14885            pw.print('/');
14886            pw.print(foreground);
14887            pw.print('/');
14888            pw.print(procState);
14889            pw.print(" trm:");
14890            if (r.trimMemoryLevel < 10) pw.print(' ');
14891            pw.print(r.trimMemoryLevel);
14892            pw.print(' ');
14893            pw.print(r.toShortString());
14894            pw.print(" (");
14895            pw.print(r.adjType);
14896            pw.println(')');
14897            if (r.adjSource != null || r.adjTarget != null) {
14898                pw.print(prefix);
14899                pw.print("    ");
14900                if (r.adjTarget instanceof ComponentName) {
14901                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14902                } else if (r.adjTarget != null) {
14903                    pw.print(r.adjTarget.toString());
14904                } else {
14905                    pw.print("{null}");
14906                }
14907                pw.print("<=");
14908                if (r.adjSource instanceof ProcessRecord) {
14909                    pw.print("Proc{");
14910                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14911                    pw.println("}");
14912                } else if (r.adjSource != null) {
14913                    pw.println(r.adjSource.toString());
14914                } else {
14915                    pw.println("{null}");
14916                }
14917            }
14918            if (inclDetails) {
14919                pw.print(prefix);
14920                pw.print("    ");
14921                pw.print("oom: max="); pw.print(r.maxAdj);
14922                pw.print(" curRaw="); pw.print(r.curRawAdj);
14923                pw.print(" setRaw="); pw.print(r.setRawAdj);
14924                pw.print(" cur="); pw.print(r.curAdj);
14925                pw.print(" set="); pw.println(r.setAdj);
14926                pw.print(prefix);
14927                pw.print("    ");
14928                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14929                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14930                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14931                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14932                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14933                pw.println();
14934                pw.print(prefix);
14935                pw.print("    ");
14936                pw.print("cached="); pw.print(r.cached);
14937                pw.print(" empty="); pw.print(r.empty);
14938                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14939
14940                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14941                    if (r.lastWakeTime != 0) {
14942                        long wtime;
14943                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14944                        synchronized (stats) {
14945                            wtime = stats.getProcessWakeTime(r.info.uid,
14946                                    r.pid, curRealtime);
14947                        }
14948                        long timeUsed = wtime - r.lastWakeTime;
14949                        pw.print(prefix);
14950                        pw.print("    ");
14951                        pw.print("keep awake over ");
14952                        TimeUtils.formatDuration(realtimeSince, pw);
14953                        pw.print(" used ");
14954                        TimeUtils.formatDuration(timeUsed, pw);
14955                        pw.print(" (");
14956                        pw.print((timeUsed*100)/realtimeSince);
14957                        pw.println("%)");
14958                    }
14959                    if (r.lastCpuTime != 0) {
14960                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14961                        pw.print(prefix);
14962                        pw.print("    ");
14963                        pw.print("run cpu over ");
14964                        TimeUtils.formatDuration(uptimeSince, pw);
14965                        pw.print(" used ");
14966                        TimeUtils.formatDuration(timeUsed, pw);
14967                        pw.print(" (");
14968                        pw.print((timeUsed*100)/uptimeSince);
14969                        pw.println("%)");
14970                    }
14971                }
14972            }
14973        }
14974        return true;
14975    }
14976
14977    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14978            String[] args) {
14979        ArrayList<ProcessRecord> procs;
14980        synchronized (this) {
14981            if (args != null && args.length > start
14982                    && args[start].charAt(0) != '-') {
14983                procs = new ArrayList<ProcessRecord>();
14984                int pid = -1;
14985                try {
14986                    pid = Integer.parseInt(args[start]);
14987                } catch (NumberFormatException e) {
14988                }
14989                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14990                    ProcessRecord proc = mLruProcesses.get(i);
14991                    if (proc.pid == pid) {
14992                        procs.add(proc);
14993                    } else if (allPkgs && proc.pkgList != null
14994                            && proc.pkgList.containsKey(args[start])) {
14995                        procs.add(proc);
14996                    } else if (proc.processName.equals(args[start])) {
14997                        procs.add(proc);
14998                    }
14999                }
15000                if (procs.size() <= 0) {
15001                    return null;
15002                }
15003            } else {
15004                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15005            }
15006        }
15007        return procs;
15008    }
15009
15010    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15011            PrintWriter pw, String[] args) {
15012        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15013        if (procs == null) {
15014            pw.println("No process found for: " + args[0]);
15015            return;
15016        }
15017
15018        long uptime = SystemClock.uptimeMillis();
15019        long realtime = SystemClock.elapsedRealtime();
15020        pw.println("Applications Graphics Acceleration Info:");
15021        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15022
15023        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15024            ProcessRecord r = procs.get(i);
15025            if (r.thread != null) {
15026                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15027                pw.flush();
15028                try {
15029                    TransferPipe tp = new TransferPipe();
15030                    try {
15031                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15032                        tp.go(fd);
15033                    } finally {
15034                        tp.kill();
15035                    }
15036                } catch (IOException e) {
15037                    pw.println("Failure while dumping the app: " + r);
15038                    pw.flush();
15039                } catch (RemoteException e) {
15040                    pw.println("Got a RemoteException while dumping the app " + r);
15041                    pw.flush();
15042                }
15043            }
15044        }
15045    }
15046
15047    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15048        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15049        if (procs == null) {
15050            pw.println("No process found for: " + args[0]);
15051            return;
15052        }
15053
15054        pw.println("Applications Database Info:");
15055
15056        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15057            ProcessRecord r = procs.get(i);
15058            if (r.thread != null) {
15059                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15060                pw.flush();
15061                try {
15062                    TransferPipe tp = new TransferPipe();
15063                    try {
15064                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15065                        tp.go(fd);
15066                    } finally {
15067                        tp.kill();
15068                    }
15069                } catch (IOException e) {
15070                    pw.println("Failure while dumping the app: " + r);
15071                    pw.flush();
15072                } catch (RemoteException e) {
15073                    pw.println("Got a RemoteException while dumping the app " + r);
15074                    pw.flush();
15075                }
15076            }
15077        }
15078    }
15079
15080    final static class MemItem {
15081        final boolean isProc;
15082        final String label;
15083        final String shortLabel;
15084        final long pss;
15085        final long swapPss;
15086        final int id;
15087        final boolean hasActivities;
15088        ArrayList<MemItem> subitems;
15089
15090        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15091                boolean _hasActivities) {
15092            isProc = true;
15093            label = _label;
15094            shortLabel = _shortLabel;
15095            pss = _pss;
15096            swapPss = _swapPss;
15097            id = _id;
15098            hasActivities = _hasActivities;
15099        }
15100
15101        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15102            isProc = false;
15103            label = _label;
15104            shortLabel = _shortLabel;
15105            pss = _pss;
15106            swapPss = _swapPss;
15107            id = _id;
15108            hasActivities = false;
15109        }
15110    }
15111
15112    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15113            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15114        if (sort && !isCompact) {
15115            Collections.sort(items, new Comparator<MemItem>() {
15116                @Override
15117                public int compare(MemItem lhs, MemItem rhs) {
15118                    if (lhs.pss < rhs.pss) {
15119                        return 1;
15120                    } else if (lhs.pss > rhs.pss) {
15121                        return -1;
15122                    }
15123                    return 0;
15124                }
15125            });
15126        }
15127
15128        for (int i=0; i<items.size(); i++) {
15129            MemItem mi = items.get(i);
15130            if (!isCompact) {
15131                if (dumpSwapPss) {
15132                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15133                            mi.label, stringifyKBSize(mi.swapPss));
15134                } else {
15135                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15136                }
15137            } else if (mi.isProc) {
15138                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15139                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15140                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15141                pw.println(mi.hasActivities ? ",a" : ",e");
15142            } else {
15143                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15144                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15145            }
15146            if (mi.subitems != null) {
15147                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15148                        true, isCompact, dumpSwapPss);
15149            }
15150        }
15151    }
15152
15153    // These are in KB.
15154    static final long[] DUMP_MEM_BUCKETS = new long[] {
15155        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15156        120*1024, 160*1024, 200*1024,
15157        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15158        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15159    };
15160
15161    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15162            boolean stackLike) {
15163        int start = label.lastIndexOf('.');
15164        if (start >= 0) start++;
15165        else start = 0;
15166        int end = label.length();
15167        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15168            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15169                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15170                out.append(bucket);
15171                out.append(stackLike ? "MB." : "MB ");
15172                out.append(label, start, end);
15173                return;
15174            }
15175        }
15176        out.append(memKB/1024);
15177        out.append(stackLike ? "MB." : "MB ");
15178        out.append(label, start, end);
15179    }
15180
15181    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15182            ProcessList.NATIVE_ADJ,
15183            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15184            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15185            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15186            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15187            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15188            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15189    };
15190    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15191            "Native",
15192            "System", "Persistent", "Persistent Service", "Foreground",
15193            "Visible", "Perceptible",
15194            "Heavy Weight", "Backup",
15195            "A Services", "Home",
15196            "Previous", "B Services", "Cached"
15197    };
15198    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15199            "native",
15200            "sys", "pers", "persvc", "fore",
15201            "vis", "percept",
15202            "heavy", "backup",
15203            "servicea", "home",
15204            "prev", "serviceb", "cached"
15205    };
15206
15207    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15208            long realtime, boolean isCheckinRequest, boolean isCompact) {
15209        if (isCompact) {
15210            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15211        }
15212        if (isCheckinRequest || isCompact) {
15213            // short checkin version
15214            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15215        } else {
15216            pw.println("Applications Memory Usage (in Kilobytes):");
15217            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15218        }
15219    }
15220
15221    private static final int KSM_SHARED = 0;
15222    private static final int KSM_SHARING = 1;
15223    private static final int KSM_UNSHARED = 2;
15224    private static final int KSM_VOLATILE = 3;
15225
15226    private final long[] getKsmInfo() {
15227        long[] longOut = new long[4];
15228        final int[] SINGLE_LONG_FORMAT = new int[] {
15229            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15230        };
15231        long[] longTmp = new long[1];
15232        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15233                SINGLE_LONG_FORMAT, null, longTmp, null);
15234        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15235        longTmp[0] = 0;
15236        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15237                SINGLE_LONG_FORMAT, null, longTmp, null);
15238        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15239        longTmp[0] = 0;
15240        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15241                SINGLE_LONG_FORMAT, null, longTmp, null);
15242        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15243        longTmp[0] = 0;
15244        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15245                SINGLE_LONG_FORMAT, null, longTmp, null);
15246        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15247        return longOut;
15248    }
15249
15250    private static String stringifySize(long size, int order) {
15251        Locale locale = Locale.US;
15252        switch (order) {
15253            case 1:
15254                return String.format(locale, "%,13d", size);
15255            case 1024:
15256                return String.format(locale, "%,9dK", size / 1024);
15257            case 1024 * 1024:
15258                return String.format(locale, "%,5dM", size / 1024 / 1024);
15259            case 1024 * 1024 * 1024:
15260                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15261            default:
15262                throw new IllegalArgumentException("Invalid size order");
15263        }
15264    }
15265
15266    private static String stringifyKBSize(long size) {
15267        return stringifySize(size * 1024, 1024);
15268    }
15269
15270    // Update this version number in case you change the 'compact' format
15271    private static final int MEMINFO_COMPACT_VERSION = 1;
15272
15273    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15274            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15275        boolean dumpDetails = false;
15276        boolean dumpFullDetails = false;
15277        boolean dumpDalvik = false;
15278        boolean dumpSummaryOnly = false;
15279        boolean dumpUnreachable = false;
15280        boolean oomOnly = false;
15281        boolean isCompact = false;
15282        boolean localOnly = false;
15283        boolean packages = false;
15284        boolean isCheckinRequest = false;
15285        boolean dumpSwapPss = false;
15286
15287        int opti = 0;
15288        while (opti < args.length) {
15289            String opt = args[opti];
15290            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15291                break;
15292            }
15293            opti++;
15294            if ("-a".equals(opt)) {
15295                dumpDetails = true;
15296                dumpFullDetails = true;
15297                dumpDalvik = true;
15298                dumpSwapPss = true;
15299            } else if ("-d".equals(opt)) {
15300                dumpDalvik = true;
15301            } else if ("-c".equals(opt)) {
15302                isCompact = true;
15303            } else if ("-s".equals(opt)) {
15304                dumpDetails = true;
15305                dumpSummaryOnly = true;
15306            } else if ("-S".equals(opt)) {
15307                dumpSwapPss = true;
15308            } else if ("--unreachable".equals(opt)) {
15309                dumpUnreachable = true;
15310            } else if ("--oom".equals(opt)) {
15311                oomOnly = true;
15312            } else if ("--local".equals(opt)) {
15313                localOnly = true;
15314            } else if ("--package".equals(opt)) {
15315                packages = true;
15316            } else if ("--checkin".equals(opt)) {
15317                isCheckinRequest = true;
15318
15319            } else if ("-h".equals(opt)) {
15320                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15321                pw.println("  -a: include all available information for each process.");
15322                pw.println("  -d: include dalvik details.");
15323                pw.println("  -c: dump in a compact machine-parseable representation.");
15324                pw.println("  -s: dump only summary of application memory usage.");
15325                pw.println("  -S: dump also SwapPss.");
15326                pw.println("  --oom: only show processes organized by oom adj.");
15327                pw.println("  --local: only collect details locally, don't call process.");
15328                pw.println("  --package: interpret process arg as package, dumping all");
15329                pw.println("             processes that have loaded that package.");
15330                pw.println("  --checkin: dump data for a checkin");
15331                pw.println("If [process] is specified it can be the name or ");
15332                pw.println("pid of a specific process to dump.");
15333                return;
15334            } else {
15335                pw.println("Unknown argument: " + opt + "; use -h for help");
15336            }
15337        }
15338
15339        long uptime = SystemClock.uptimeMillis();
15340        long realtime = SystemClock.elapsedRealtime();
15341        final long[] tmpLong = new long[1];
15342
15343        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15344        if (procs == null) {
15345            // No Java processes.  Maybe they want to print a native process.
15346            if (args != null && args.length > opti
15347                    && args[opti].charAt(0) != '-') {
15348                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15349                        = new ArrayList<ProcessCpuTracker.Stats>();
15350                updateCpuStatsNow();
15351                int findPid = -1;
15352                try {
15353                    findPid = Integer.parseInt(args[opti]);
15354                } catch (NumberFormatException e) {
15355                }
15356                synchronized (mProcessCpuTracker) {
15357                    final int N = mProcessCpuTracker.countStats();
15358                    for (int i=0; i<N; i++) {
15359                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15360                        if (st.pid == findPid || (st.baseName != null
15361                                && st.baseName.equals(args[opti]))) {
15362                            nativeProcs.add(st);
15363                        }
15364                    }
15365                }
15366                if (nativeProcs.size() > 0) {
15367                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15368                            isCompact);
15369                    Debug.MemoryInfo mi = null;
15370                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15371                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15372                        final int pid = r.pid;
15373                        if (!isCheckinRequest && dumpDetails) {
15374                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15375                        }
15376                        if (mi == null) {
15377                            mi = new Debug.MemoryInfo();
15378                        }
15379                        if (dumpDetails || (!brief && !oomOnly)) {
15380                            Debug.getMemoryInfo(pid, mi);
15381                        } else {
15382                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15383                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15384                        }
15385                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15386                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15387                        if (isCheckinRequest) {
15388                            pw.println();
15389                        }
15390                    }
15391                    return;
15392                }
15393            }
15394            pw.println("No process found for: " + args[opti]);
15395            return;
15396        }
15397
15398        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15399            dumpDetails = true;
15400        }
15401
15402        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15403
15404        String[] innerArgs = new String[args.length-opti];
15405        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15406
15407        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15408        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15409        long nativePss = 0;
15410        long nativeSwapPss = 0;
15411        long dalvikPss = 0;
15412        long dalvikSwapPss = 0;
15413        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15414                EmptyArray.LONG;
15415        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15416                EmptyArray.LONG;
15417        long otherPss = 0;
15418        long otherSwapPss = 0;
15419        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15420        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15421
15422        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15423        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15424        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15425                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15426
15427        long totalPss = 0;
15428        long totalSwapPss = 0;
15429        long cachedPss = 0;
15430        long cachedSwapPss = 0;
15431        boolean hasSwapPss = false;
15432
15433        Debug.MemoryInfo mi = null;
15434        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15435            final ProcessRecord r = procs.get(i);
15436            final IApplicationThread thread;
15437            final int pid;
15438            final int oomAdj;
15439            final boolean hasActivities;
15440            synchronized (this) {
15441                thread = r.thread;
15442                pid = r.pid;
15443                oomAdj = r.getSetAdjWithServices();
15444                hasActivities = r.activities.size() > 0;
15445            }
15446            if (thread != null) {
15447                if (!isCheckinRequest && dumpDetails) {
15448                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15449                }
15450                if (mi == null) {
15451                    mi = new Debug.MemoryInfo();
15452                }
15453                if (dumpDetails || (!brief && !oomOnly)) {
15454                    Debug.getMemoryInfo(pid, mi);
15455                    hasSwapPss = mi.hasSwappedOutPss;
15456                } else {
15457                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15458                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15459                }
15460                if (dumpDetails) {
15461                    if (localOnly) {
15462                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15463                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15464                        if (isCheckinRequest) {
15465                            pw.println();
15466                        }
15467                    } else {
15468                        try {
15469                            pw.flush();
15470                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15471                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15472                        } catch (RemoteException e) {
15473                            if (!isCheckinRequest) {
15474                                pw.println("Got RemoteException!");
15475                                pw.flush();
15476                            }
15477                        }
15478                    }
15479                }
15480
15481                final long myTotalPss = mi.getTotalPss();
15482                final long myTotalUss = mi.getTotalUss();
15483                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15484
15485                synchronized (this) {
15486                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15487                        // Record this for posterity if the process has been stable.
15488                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15489                    }
15490                }
15491
15492                if (!isCheckinRequest && mi != null) {
15493                    totalPss += myTotalPss;
15494                    totalSwapPss += myTotalSwapPss;
15495                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15496                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15497                            myTotalSwapPss, pid, hasActivities);
15498                    procMems.add(pssItem);
15499                    procMemsMap.put(pid, pssItem);
15500
15501                    nativePss += mi.nativePss;
15502                    nativeSwapPss += mi.nativeSwappedOutPss;
15503                    dalvikPss += mi.dalvikPss;
15504                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15505                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15506                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15507                        dalvikSubitemSwapPss[j] +=
15508                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15509                    }
15510                    otherPss += mi.otherPss;
15511                    otherSwapPss += mi.otherSwappedOutPss;
15512                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15513                        long mem = mi.getOtherPss(j);
15514                        miscPss[j] += mem;
15515                        otherPss -= mem;
15516                        mem = mi.getOtherSwappedOutPss(j);
15517                        miscSwapPss[j] += mem;
15518                        otherSwapPss -= mem;
15519                    }
15520
15521                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15522                        cachedPss += myTotalPss;
15523                        cachedSwapPss += myTotalSwapPss;
15524                    }
15525
15526                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15527                        if (oomIndex == (oomPss.length - 1)
15528                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15529                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15530                            oomPss[oomIndex] += myTotalPss;
15531                            oomSwapPss[oomIndex] += myTotalSwapPss;
15532                            if (oomProcs[oomIndex] == null) {
15533                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15534                            }
15535                            oomProcs[oomIndex].add(pssItem);
15536                            break;
15537                        }
15538                    }
15539                }
15540            }
15541        }
15542
15543        long nativeProcTotalPss = 0;
15544
15545        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15546            // If we are showing aggregations, also look for native processes to
15547            // include so that our aggregations are more accurate.
15548            updateCpuStatsNow();
15549            mi = null;
15550            synchronized (mProcessCpuTracker) {
15551                final int N = mProcessCpuTracker.countStats();
15552                for (int i=0; i<N; i++) {
15553                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15554                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15555                        if (mi == null) {
15556                            mi = new Debug.MemoryInfo();
15557                        }
15558                        if (!brief && !oomOnly) {
15559                            Debug.getMemoryInfo(st.pid, mi);
15560                        } else {
15561                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15562                            mi.nativePrivateDirty = (int)tmpLong[0];
15563                        }
15564
15565                        final long myTotalPss = mi.getTotalPss();
15566                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15567                        totalPss += myTotalPss;
15568                        nativeProcTotalPss += myTotalPss;
15569
15570                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15571                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15572                        procMems.add(pssItem);
15573
15574                        nativePss += mi.nativePss;
15575                        nativeSwapPss += mi.nativeSwappedOutPss;
15576                        dalvikPss += mi.dalvikPss;
15577                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15578                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15579                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15580                            dalvikSubitemSwapPss[j] +=
15581                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15582                        }
15583                        otherPss += mi.otherPss;
15584                        otherSwapPss += mi.otherSwappedOutPss;
15585                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15586                            long mem = mi.getOtherPss(j);
15587                            miscPss[j] += mem;
15588                            otherPss -= mem;
15589                            mem = mi.getOtherSwappedOutPss(j);
15590                            miscSwapPss[j] += mem;
15591                            otherSwapPss -= mem;
15592                        }
15593                        oomPss[0] += myTotalPss;
15594                        oomSwapPss[0] += myTotalSwapPss;
15595                        if (oomProcs[0] == null) {
15596                            oomProcs[0] = new ArrayList<MemItem>();
15597                        }
15598                        oomProcs[0].add(pssItem);
15599                    }
15600                }
15601            }
15602
15603            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15604
15605            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15606            final MemItem dalvikItem =
15607                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15608            if (dalvikSubitemPss.length > 0) {
15609                dalvikItem.subitems = new ArrayList<MemItem>();
15610                for (int j=0; j<dalvikSubitemPss.length; j++) {
15611                    final String name = Debug.MemoryInfo.getOtherLabel(
15612                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15613                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15614                                    dalvikSubitemSwapPss[j], j));
15615                }
15616            }
15617            catMems.add(dalvikItem);
15618            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15619            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15620                String label = Debug.MemoryInfo.getOtherLabel(j);
15621                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15622            }
15623
15624            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15625            for (int j=0; j<oomPss.length; j++) {
15626                if (oomPss[j] != 0) {
15627                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15628                            : DUMP_MEM_OOM_LABEL[j];
15629                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15630                            DUMP_MEM_OOM_ADJ[j]);
15631                    item.subitems = oomProcs[j];
15632                    oomMems.add(item);
15633                }
15634            }
15635
15636            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15637            if (!brief && !oomOnly && !isCompact) {
15638                pw.println();
15639                pw.println("Total PSS by process:");
15640                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15641                pw.println();
15642            }
15643            if (!isCompact) {
15644                pw.println("Total PSS by OOM adjustment:");
15645            }
15646            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15647            if (!brief && !oomOnly) {
15648                PrintWriter out = categoryPw != null ? categoryPw : pw;
15649                if (!isCompact) {
15650                    out.println();
15651                    out.println("Total PSS by category:");
15652                }
15653                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15654            }
15655            if (!isCompact) {
15656                pw.println();
15657            }
15658            MemInfoReader memInfo = new MemInfoReader();
15659            memInfo.readMemInfo();
15660            if (nativeProcTotalPss > 0) {
15661                synchronized (this) {
15662                    final long cachedKb = memInfo.getCachedSizeKb();
15663                    final long freeKb = memInfo.getFreeSizeKb();
15664                    final long zramKb = memInfo.getZramTotalSizeKb();
15665                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15666                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15667                            kernelKb*1024, nativeProcTotalPss*1024);
15668                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15669                            nativeProcTotalPss);
15670                }
15671            }
15672            if (!brief) {
15673                if (!isCompact) {
15674                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15675                    pw.print(" (status ");
15676                    switch (mLastMemoryLevel) {
15677                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15678                            pw.println("normal)");
15679                            break;
15680                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15681                            pw.println("moderate)");
15682                            break;
15683                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15684                            pw.println("low)");
15685                            break;
15686                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15687                            pw.println("critical)");
15688                            break;
15689                        default:
15690                            pw.print(mLastMemoryLevel);
15691                            pw.println(")");
15692                            break;
15693                    }
15694                    pw.print(" Free RAM: ");
15695                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15696                            + memInfo.getFreeSizeKb()));
15697                    pw.print(" (");
15698                    pw.print(stringifyKBSize(cachedPss));
15699                    pw.print(" cached pss + ");
15700                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15701                    pw.print(" cached kernel + ");
15702                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15703                    pw.println(" free)");
15704                } else {
15705                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15706                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15707                            + memInfo.getFreeSizeKb()); pw.print(",");
15708                    pw.println(totalPss - cachedPss);
15709                }
15710            }
15711            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15712                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15713                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15714            if (!isCompact) {
15715                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15716                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15717                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15718                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15719                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15720            } else {
15721                pw.print("lostram,"); pw.println(lostRAM);
15722            }
15723            if (!brief) {
15724                if (memInfo.getZramTotalSizeKb() != 0) {
15725                    if (!isCompact) {
15726                        pw.print("     ZRAM: ");
15727                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15728                                pw.print(" physical used for ");
15729                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15730                                        - memInfo.getSwapFreeSizeKb()));
15731                                pw.print(" in swap (");
15732                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15733                                pw.println(" total swap)");
15734                    } else {
15735                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15736                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15737                                pw.println(memInfo.getSwapFreeSizeKb());
15738                    }
15739                }
15740                final long[] ksm = getKsmInfo();
15741                if (!isCompact) {
15742                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15743                            || ksm[KSM_VOLATILE] != 0) {
15744                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15745                                pw.print(" saved from shared ");
15746                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15747                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15748                                pw.print(" unshared; ");
15749                                pw.print(stringifyKBSize(
15750                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15751                    }
15752                    pw.print("   Tuning: ");
15753                    pw.print(ActivityManager.staticGetMemoryClass());
15754                    pw.print(" (large ");
15755                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15756                    pw.print("), oom ");
15757                    pw.print(stringifySize(
15758                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15759                    pw.print(", restore limit ");
15760                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15761                    if (ActivityManager.isLowRamDeviceStatic()) {
15762                        pw.print(" (low-ram)");
15763                    }
15764                    if (ActivityManager.isHighEndGfx()) {
15765                        pw.print(" (high-end-gfx)");
15766                    }
15767                    pw.println();
15768                } else {
15769                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15770                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15771                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15772                    pw.print("tuning,");
15773                    pw.print(ActivityManager.staticGetMemoryClass());
15774                    pw.print(',');
15775                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15776                    pw.print(',');
15777                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15778                    if (ActivityManager.isLowRamDeviceStatic()) {
15779                        pw.print(",low-ram");
15780                    }
15781                    if (ActivityManager.isHighEndGfx()) {
15782                        pw.print(",high-end-gfx");
15783                    }
15784                    pw.println();
15785                }
15786            }
15787        }
15788    }
15789
15790    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15791            long memtrack, String name) {
15792        sb.append("  ");
15793        sb.append(ProcessList.makeOomAdjString(oomAdj));
15794        sb.append(' ');
15795        sb.append(ProcessList.makeProcStateString(procState));
15796        sb.append(' ');
15797        ProcessList.appendRamKb(sb, pss);
15798        sb.append(": ");
15799        sb.append(name);
15800        if (memtrack > 0) {
15801            sb.append(" (");
15802            sb.append(stringifyKBSize(memtrack));
15803            sb.append(" memtrack)");
15804        }
15805    }
15806
15807    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15808        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15809        sb.append(" (pid ");
15810        sb.append(mi.pid);
15811        sb.append(") ");
15812        sb.append(mi.adjType);
15813        sb.append('\n');
15814        if (mi.adjReason != null) {
15815            sb.append("                      ");
15816            sb.append(mi.adjReason);
15817            sb.append('\n');
15818        }
15819    }
15820
15821    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15822        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15823        for (int i=0, N=memInfos.size(); i<N; i++) {
15824            ProcessMemInfo mi = memInfos.get(i);
15825            infoMap.put(mi.pid, mi);
15826        }
15827        updateCpuStatsNow();
15828        long[] memtrackTmp = new long[1];
15829        synchronized (mProcessCpuTracker) {
15830            final int N = mProcessCpuTracker.countStats();
15831            for (int i=0; i<N; i++) {
15832                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15833                if (st.vsize > 0) {
15834                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15835                    if (pss > 0) {
15836                        if (infoMap.indexOfKey(st.pid) < 0) {
15837                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15838                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15839                            mi.pss = pss;
15840                            mi.memtrack = memtrackTmp[0];
15841                            memInfos.add(mi);
15842                        }
15843                    }
15844                }
15845            }
15846        }
15847
15848        long totalPss = 0;
15849        long totalMemtrack = 0;
15850        for (int i=0, N=memInfos.size(); i<N; i++) {
15851            ProcessMemInfo mi = memInfos.get(i);
15852            if (mi.pss == 0) {
15853                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15854                mi.memtrack = memtrackTmp[0];
15855            }
15856            totalPss += mi.pss;
15857            totalMemtrack += mi.memtrack;
15858        }
15859        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15860            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15861                if (lhs.oomAdj != rhs.oomAdj) {
15862                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15863                }
15864                if (lhs.pss != rhs.pss) {
15865                    return lhs.pss < rhs.pss ? 1 : -1;
15866                }
15867                return 0;
15868            }
15869        });
15870
15871        StringBuilder tag = new StringBuilder(128);
15872        StringBuilder stack = new StringBuilder(128);
15873        tag.append("Low on memory -- ");
15874        appendMemBucket(tag, totalPss, "total", false);
15875        appendMemBucket(stack, totalPss, "total", true);
15876
15877        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15878        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15879        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15880
15881        boolean firstLine = true;
15882        int lastOomAdj = Integer.MIN_VALUE;
15883        long extraNativeRam = 0;
15884        long extraNativeMemtrack = 0;
15885        long cachedPss = 0;
15886        for (int i=0, N=memInfos.size(); i<N; i++) {
15887            ProcessMemInfo mi = memInfos.get(i);
15888
15889            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15890                cachedPss += mi.pss;
15891            }
15892
15893            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15894                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15895                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15896                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15897                if (lastOomAdj != mi.oomAdj) {
15898                    lastOomAdj = mi.oomAdj;
15899                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15900                        tag.append(" / ");
15901                    }
15902                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15903                        if (firstLine) {
15904                            stack.append(":");
15905                            firstLine = false;
15906                        }
15907                        stack.append("\n\t at ");
15908                    } else {
15909                        stack.append("$");
15910                    }
15911                } else {
15912                    tag.append(" ");
15913                    stack.append("$");
15914                }
15915                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15916                    appendMemBucket(tag, mi.pss, mi.name, false);
15917                }
15918                appendMemBucket(stack, mi.pss, mi.name, true);
15919                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15920                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15921                    stack.append("(");
15922                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15923                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15924                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15925                            stack.append(":");
15926                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15927                        }
15928                    }
15929                    stack.append(")");
15930                }
15931            }
15932
15933            appendMemInfo(fullNativeBuilder, mi);
15934            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15935                // The short form only has native processes that are >= 512K.
15936                if (mi.pss >= 512) {
15937                    appendMemInfo(shortNativeBuilder, mi);
15938                } else {
15939                    extraNativeRam += mi.pss;
15940                    extraNativeMemtrack += mi.memtrack;
15941                }
15942            } else {
15943                // Short form has all other details, but if we have collected RAM
15944                // from smaller native processes let's dump a summary of that.
15945                if (extraNativeRam > 0) {
15946                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15947                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15948                    shortNativeBuilder.append('\n');
15949                    extraNativeRam = 0;
15950                }
15951                appendMemInfo(fullJavaBuilder, mi);
15952            }
15953        }
15954
15955        fullJavaBuilder.append("           ");
15956        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15957        fullJavaBuilder.append(": TOTAL");
15958        if (totalMemtrack > 0) {
15959            fullJavaBuilder.append(" (");
15960            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15961            fullJavaBuilder.append(" memtrack)");
15962        } else {
15963        }
15964        fullJavaBuilder.append("\n");
15965
15966        MemInfoReader memInfo = new MemInfoReader();
15967        memInfo.readMemInfo();
15968        final long[] infos = memInfo.getRawInfo();
15969
15970        StringBuilder memInfoBuilder = new StringBuilder(1024);
15971        Debug.getMemInfo(infos);
15972        memInfoBuilder.append("  MemInfo: ");
15973        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15974        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15975        memInfoBuilder.append(stringifyKBSize(
15976                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15977        memInfoBuilder.append(stringifyKBSize(
15978                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15979        memInfoBuilder.append(stringifyKBSize(
15980                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15981        memInfoBuilder.append("           ");
15982        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15983        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15984        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15985        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15986        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15987            memInfoBuilder.append("  ZRAM: ");
15988            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15989            memInfoBuilder.append(" RAM, ");
15990            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15991            memInfoBuilder.append(" swap total, ");
15992            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15993            memInfoBuilder.append(" swap free\n");
15994        }
15995        final long[] ksm = getKsmInfo();
15996        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15997                || ksm[KSM_VOLATILE] != 0) {
15998            memInfoBuilder.append("  KSM: ");
15999            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16000            memInfoBuilder.append(" saved from shared ");
16001            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16002            memInfoBuilder.append("\n       ");
16003            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16004            memInfoBuilder.append(" unshared; ");
16005            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16006            memInfoBuilder.append(" volatile\n");
16007        }
16008        memInfoBuilder.append("  Free RAM: ");
16009        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16010                + memInfo.getFreeSizeKb()));
16011        memInfoBuilder.append("\n");
16012        memInfoBuilder.append("  Used RAM: ");
16013        memInfoBuilder.append(stringifyKBSize(
16014                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16015        memInfoBuilder.append("\n");
16016        memInfoBuilder.append("  Lost RAM: ");
16017        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16018                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16019                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16020        memInfoBuilder.append("\n");
16021        Slog.i(TAG, "Low on memory:");
16022        Slog.i(TAG, shortNativeBuilder.toString());
16023        Slog.i(TAG, fullJavaBuilder.toString());
16024        Slog.i(TAG, memInfoBuilder.toString());
16025
16026        StringBuilder dropBuilder = new StringBuilder(1024);
16027        /*
16028        StringWriter oomSw = new StringWriter();
16029        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16030        StringWriter catSw = new StringWriter();
16031        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16032        String[] emptyArgs = new String[] { };
16033        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16034        oomPw.flush();
16035        String oomString = oomSw.toString();
16036        */
16037        dropBuilder.append("Low on memory:");
16038        dropBuilder.append(stack);
16039        dropBuilder.append('\n');
16040        dropBuilder.append(fullNativeBuilder);
16041        dropBuilder.append(fullJavaBuilder);
16042        dropBuilder.append('\n');
16043        dropBuilder.append(memInfoBuilder);
16044        dropBuilder.append('\n');
16045        /*
16046        dropBuilder.append(oomString);
16047        dropBuilder.append('\n');
16048        */
16049        StringWriter catSw = new StringWriter();
16050        synchronized (ActivityManagerService.this) {
16051            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16052            String[] emptyArgs = new String[] { };
16053            catPw.println();
16054            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16055            catPw.println();
16056            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16057                    false, false, null);
16058            catPw.println();
16059            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16060            catPw.flush();
16061        }
16062        dropBuilder.append(catSw.toString());
16063        addErrorToDropBox("lowmem", null, "system_server", null,
16064                null, tag.toString(), dropBuilder.toString(), null, null);
16065        //Slog.i(TAG, "Sent to dropbox:");
16066        //Slog.i(TAG, dropBuilder.toString());
16067        synchronized (ActivityManagerService.this) {
16068            long now = SystemClock.uptimeMillis();
16069            if (mLastMemUsageReportTime < now) {
16070                mLastMemUsageReportTime = now;
16071            }
16072        }
16073    }
16074
16075    /**
16076     * Searches array of arguments for the specified string
16077     * @param args array of argument strings
16078     * @param value value to search for
16079     * @return true if the value is contained in the array
16080     */
16081    private static boolean scanArgs(String[] args, String value) {
16082        if (args != null) {
16083            for (String arg : args) {
16084                if (value.equals(arg)) {
16085                    return true;
16086                }
16087            }
16088        }
16089        return false;
16090    }
16091
16092    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16093            ContentProviderRecord cpr, boolean always) {
16094        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16095
16096        if (!inLaunching || always) {
16097            synchronized (cpr) {
16098                cpr.launchingApp = null;
16099                cpr.notifyAll();
16100            }
16101            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16102            String names[] = cpr.info.authority.split(";");
16103            for (int j = 0; j < names.length; j++) {
16104                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16105            }
16106        }
16107
16108        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16109            ContentProviderConnection conn = cpr.connections.get(i);
16110            if (conn.waiting) {
16111                // If this connection is waiting for the provider, then we don't
16112                // need to mess with its process unless we are always removing
16113                // or for some reason the provider is not currently launching.
16114                if (inLaunching && !always) {
16115                    continue;
16116                }
16117            }
16118            ProcessRecord capp = conn.client;
16119            conn.dead = true;
16120            if (conn.stableCount > 0) {
16121                if (!capp.persistent && capp.thread != null
16122                        && capp.pid != 0
16123                        && capp.pid != MY_PID) {
16124                    capp.kill("depends on provider "
16125                            + cpr.name.flattenToShortString()
16126                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16127                }
16128            } else if (capp.thread != null && conn.provider.provider != null) {
16129                try {
16130                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16131                } catch (RemoteException e) {
16132                }
16133                // In the protocol here, we don't expect the client to correctly
16134                // clean up this connection, we'll just remove it.
16135                cpr.connections.remove(i);
16136                if (conn.client.conProviders.remove(conn)) {
16137                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16138                }
16139            }
16140        }
16141
16142        if (inLaunching && always) {
16143            mLaunchingProviders.remove(cpr);
16144        }
16145        return inLaunching;
16146    }
16147
16148    /**
16149     * Main code for cleaning up a process when it has gone away.  This is
16150     * called both as a result of the process dying, or directly when stopping
16151     * a process when running in single process mode.
16152     *
16153     * @return Returns true if the given process has been restarted, so the
16154     * app that was passed in must remain on the process lists.
16155     */
16156    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16157            boolean restarting, boolean allowRestart, int index) {
16158        if (index >= 0) {
16159            removeLruProcessLocked(app);
16160            ProcessList.remove(app.pid);
16161        }
16162
16163        mProcessesToGc.remove(app);
16164        mPendingPssProcesses.remove(app);
16165
16166        // Dismiss any open dialogs.
16167        if (app.crashDialog != null && !app.forceCrashReport) {
16168            app.crashDialog.dismiss();
16169            app.crashDialog = null;
16170        }
16171        if (app.anrDialog != null) {
16172            app.anrDialog.dismiss();
16173            app.anrDialog = null;
16174        }
16175        if (app.waitDialog != null) {
16176            app.waitDialog.dismiss();
16177            app.waitDialog = null;
16178        }
16179
16180        app.crashing = false;
16181        app.notResponding = false;
16182
16183        app.resetPackageList(mProcessStats);
16184        app.unlinkDeathRecipient();
16185        app.makeInactive(mProcessStats);
16186        app.waitingToKill = null;
16187        app.forcingToForeground = null;
16188        updateProcessForegroundLocked(app, false, false);
16189        app.foregroundActivities = false;
16190        app.hasShownUi = false;
16191        app.treatLikeActivity = false;
16192        app.hasAboveClient = false;
16193        app.hasClientActivities = false;
16194
16195        mServices.killServicesLocked(app, allowRestart);
16196
16197        boolean restart = false;
16198
16199        // Remove published content providers.
16200        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16201            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16202            final boolean always = app.bad || !allowRestart;
16203            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16204            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16205                // We left the provider in the launching list, need to
16206                // restart it.
16207                restart = true;
16208            }
16209
16210            cpr.provider = null;
16211            cpr.proc = null;
16212        }
16213        app.pubProviders.clear();
16214
16215        // Take care of any launching providers waiting for this process.
16216        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16217            restart = true;
16218        }
16219
16220        // Unregister from connected content providers.
16221        if (!app.conProviders.isEmpty()) {
16222            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16223                ContentProviderConnection conn = app.conProviders.get(i);
16224                conn.provider.connections.remove(conn);
16225                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16226                        conn.provider.name);
16227            }
16228            app.conProviders.clear();
16229        }
16230
16231        // At this point there may be remaining entries in mLaunchingProviders
16232        // where we were the only one waiting, so they are no longer of use.
16233        // Look for these and clean up if found.
16234        // XXX Commented out for now.  Trying to figure out a way to reproduce
16235        // the actual situation to identify what is actually going on.
16236        if (false) {
16237            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16238                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16239                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16240                    synchronized (cpr) {
16241                        cpr.launchingApp = null;
16242                        cpr.notifyAll();
16243                    }
16244                }
16245            }
16246        }
16247
16248        skipCurrentReceiverLocked(app);
16249
16250        // Unregister any receivers.
16251        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16252            removeReceiverLocked(app.receivers.valueAt(i));
16253        }
16254        app.receivers.clear();
16255
16256        // If the app is undergoing backup, tell the backup manager about it
16257        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16258            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16259                    + mBackupTarget.appInfo + " died during backup");
16260            try {
16261                IBackupManager bm = IBackupManager.Stub.asInterface(
16262                        ServiceManager.getService(Context.BACKUP_SERVICE));
16263                bm.agentDisconnected(app.info.packageName);
16264            } catch (RemoteException e) {
16265                // can't happen; backup manager is local
16266            }
16267        }
16268
16269        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16270            ProcessChangeItem item = mPendingProcessChanges.get(i);
16271            if (item.pid == app.pid) {
16272                mPendingProcessChanges.remove(i);
16273                mAvailProcessChanges.add(item);
16274            }
16275        }
16276        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16277                null).sendToTarget();
16278
16279        // If the caller is restarting this app, then leave it in its
16280        // current lists and let the caller take care of it.
16281        if (restarting) {
16282            return false;
16283        }
16284
16285        if (!app.persistent || app.isolated) {
16286            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16287                    "Removing non-persistent process during cleanup: " + app);
16288            removeProcessNameLocked(app.processName, app.uid);
16289            if (mHeavyWeightProcess == app) {
16290                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16291                        mHeavyWeightProcess.userId, 0));
16292                mHeavyWeightProcess = null;
16293            }
16294        } else if (!app.removed) {
16295            // This app is persistent, so we need to keep its record around.
16296            // If it is not already on the pending app list, add it there
16297            // and start a new process for it.
16298            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16299                mPersistentStartingProcesses.add(app);
16300                restart = true;
16301            }
16302        }
16303        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16304                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16305        mProcessesOnHold.remove(app);
16306
16307        if (app == mHomeProcess) {
16308            mHomeProcess = null;
16309        }
16310        if (app == mPreviousProcess) {
16311            mPreviousProcess = null;
16312        }
16313
16314        if (restart && !app.isolated) {
16315            // We have components that still need to be running in the
16316            // process, so re-launch it.
16317            if (index < 0) {
16318                ProcessList.remove(app.pid);
16319            }
16320            addProcessNameLocked(app);
16321            startProcessLocked(app, "restart", app.processName);
16322            return true;
16323        } else if (app.pid > 0 && app.pid != MY_PID) {
16324            // Goodbye!
16325            boolean removed;
16326            synchronized (mPidsSelfLocked) {
16327                mPidsSelfLocked.remove(app.pid);
16328                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16329            }
16330            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16331            if (app.isolated) {
16332                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16333            }
16334            app.setPid(0);
16335        }
16336        return false;
16337    }
16338
16339    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16340        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16341            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16342            if (cpr.launchingApp == app) {
16343                return true;
16344            }
16345        }
16346        return false;
16347    }
16348
16349    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16350        // Look through the content providers we are waiting to have launched,
16351        // and if any run in this process then either schedule a restart of
16352        // the process or kill the client waiting for it if this process has
16353        // gone bad.
16354        boolean restart = false;
16355        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16356            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16357            if (cpr.launchingApp == app) {
16358                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16359                    restart = true;
16360                } else {
16361                    removeDyingProviderLocked(app, cpr, true);
16362                }
16363            }
16364        }
16365        return restart;
16366    }
16367
16368    // =========================================================
16369    // SERVICES
16370    // =========================================================
16371
16372    @Override
16373    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16374            int flags) {
16375        enforceNotIsolatedCaller("getServices");
16376        synchronized (this) {
16377            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16378        }
16379    }
16380
16381    @Override
16382    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16383        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16384        synchronized (this) {
16385            return mServices.getRunningServiceControlPanelLocked(name);
16386        }
16387    }
16388
16389    @Override
16390    public ComponentName startService(IApplicationThread caller, Intent service,
16391            String resolvedType, String callingPackage, int userId)
16392            throws TransactionTooLargeException {
16393        enforceNotIsolatedCaller("startService");
16394        // Refuse possible leaked file descriptors
16395        if (service != null && service.hasFileDescriptors() == true) {
16396            throw new IllegalArgumentException("File descriptors passed in Intent");
16397        }
16398
16399        if (callingPackage == null) {
16400            throw new IllegalArgumentException("callingPackage cannot be null");
16401        }
16402
16403        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16404                "startService: " + service + " type=" + resolvedType);
16405        synchronized(this) {
16406            final int callingPid = Binder.getCallingPid();
16407            final int callingUid = Binder.getCallingUid();
16408            final long origId = Binder.clearCallingIdentity();
16409            ComponentName res = mServices.startServiceLocked(caller, service,
16410                    resolvedType, callingPid, callingUid, callingPackage, userId);
16411            Binder.restoreCallingIdentity(origId);
16412            return res;
16413        }
16414    }
16415
16416    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16417            String callingPackage, int userId)
16418            throws TransactionTooLargeException {
16419        synchronized(this) {
16420            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16421                    "startServiceInPackage: " + service + " type=" + resolvedType);
16422            final long origId = Binder.clearCallingIdentity();
16423            ComponentName res = mServices.startServiceLocked(null, service,
16424                    resolvedType, -1, uid, callingPackage, userId);
16425            Binder.restoreCallingIdentity(origId);
16426            return res;
16427        }
16428    }
16429
16430    @Override
16431    public int stopService(IApplicationThread caller, Intent service,
16432            String resolvedType, int userId) {
16433        enforceNotIsolatedCaller("stopService");
16434        // Refuse possible leaked file descriptors
16435        if (service != null && service.hasFileDescriptors() == true) {
16436            throw new IllegalArgumentException("File descriptors passed in Intent");
16437        }
16438
16439        synchronized(this) {
16440            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16441        }
16442    }
16443
16444    @Override
16445    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16446        enforceNotIsolatedCaller("peekService");
16447        // Refuse possible leaked file descriptors
16448        if (service != null && service.hasFileDescriptors() == true) {
16449            throw new IllegalArgumentException("File descriptors passed in Intent");
16450        }
16451
16452        if (callingPackage == null) {
16453            throw new IllegalArgumentException("callingPackage cannot be null");
16454        }
16455
16456        synchronized(this) {
16457            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16458        }
16459    }
16460
16461    @Override
16462    public boolean stopServiceToken(ComponentName className, IBinder token,
16463            int startId) {
16464        synchronized(this) {
16465            return mServices.stopServiceTokenLocked(className, token, startId);
16466        }
16467    }
16468
16469    @Override
16470    public void setServiceForeground(ComponentName className, IBinder token,
16471            int id, Notification notification, int flags) {
16472        synchronized(this) {
16473            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16474        }
16475    }
16476
16477    @Override
16478    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16479            boolean requireFull, String name, String callerPackage) {
16480        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16481                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16482    }
16483
16484    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16485            String className, int flags) {
16486        boolean result = false;
16487        // For apps that don't have pre-defined UIDs, check for permission
16488        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16489            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16490                if (ActivityManager.checkUidPermission(
16491                        INTERACT_ACROSS_USERS,
16492                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16493                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16494                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16495                            + " requests FLAG_SINGLE_USER, but app does not hold "
16496                            + INTERACT_ACROSS_USERS;
16497                    Slog.w(TAG, msg);
16498                    throw new SecurityException(msg);
16499                }
16500                // Permission passed
16501                result = true;
16502            }
16503        } else if ("system".equals(componentProcessName)) {
16504            result = true;
16505        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16506            // Phone app and persistent apps are allowed to export singleuser providers.
16507            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16508                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16509        }
16510        if (DEBUG_MU) Slog.v(TAG_MU,
16511                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16512                + Integer.toHexString(flags) + ") = " + result);
16513        return result;
16514    }
16515
16516    /**
16517     * Checks to see if the caller is in the same app as the singleton
16518     * component, or the component is in a special app. It allows special apps
16519     * to export singleton components but prevents exporting singleton
16520     * components for regular apps.
16521     */
16522    boolean isValidSingletonCall(int callingUid, int componentUid) {
16523        int componentAppId = UserHandle.getAppId(componentUid);
16524        return UserHandle.isSameApp(callingUid, componentUid)
16525                || componentAppId == Process.SYSTEM_UID
16526                || componentAppId == Process.PHONE_UID
16527                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16528                        == PackageManager.PERMISSION_GRANTED;
16529    }
16530
16531    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16532            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16533            int userId) throws TransactionTooLargeException {
16534        enforceNotIsolatedCaller("bindService");
16535
16536        // Refuse possible leaked file descriptors
16537        if (service != null && service.hasFileDescriptors() == true) {
16538            throw new IllegalArgumentException("File descriptors passed in Intent");
16539        }
16540
16541        if (callingPackage == null) {
16542            throw new IllegalArgumentException("callingPackage cannot be null");
16543        }
16544
16545        synchronized(this) {
16546            return mServices.bindServiceLocked(caller, token, service,
16547                    resolvedType, connection, flags, callingPackage, userId);
16548        }
16549    }
16550
16551    public boolean unbindService(IServiceConnection connection) {
16552        synchronized (this) {
16553            return mServices.unbindServiceLocked(connection);
16554        }
16555    }
16556
16557    public void publishService(IBinder token, Intent intent, IBinder service) {
16558        // Refuse possible leaked file descriptors
16559        if (intent != null && intent.hasFileDescriptors() == true) {
16560            throw new IllegalArgumentException("File descriptors passed in Intent");
16561        }
16562
16563        synchronized(this) {
16564            if (!(token instanceof ServiceRecord)) {
16565                throw new IllegalArgumentException("Invalid service token");
16566            }
16567            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16568        }
16569    }
16570
16571    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16572        // Refuse possible leaked file descriptors
16573        if (intent != null && intent.hasFileDescriptors() == true) {
16574            throw new IllegalArgumentException("File descriptors passed in Intent");
16575        }
16576
16577        synchronized(this) {
16578            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16579        }
16580    }
16581
16582    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16583        synchronized(this) {
16584            if (!(token instanceof ServiceRecord)) {
16585                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16586                throw new IllegalArgumentException("Invalid service token");
16587            }
16588            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16589        }
16590    }
16591
16592    // =========================================================
16593    // BACKUP AND RESTORE
16594    // =========================================================
16595
16596    // Cause the target app to be launched if necessary and its backup agent
16597    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16598    // activity manager to announce its creation.
16599    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16600        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16601                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16602        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16603
16604        synchronized(this) {
16605            // !!! TODO: currently no check here that we're already bound
16606            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16607            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16608            synchronized (stats) {
16609                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16610            }
16611
16612            // Backup agent is now in use, its package can't be stopped.
16613            try {
16614                AppGlobals.getPackageManager().setPackageStoppedState(
16615                        app.packageName, false, UserHandle.getUserId(app.uid));
16616            } catch (RemoteException e) {
16617            } catch (IllegalArgumentException e) {
16618                Slog.w(TAG, "Failed trying to unstop package "
16619                        + app.packageName + ": " + e);
16620            }
16621
16622            BackupRecord r = new BackupRecord(ss, app, backupMode);
16623            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16624                    ? new ComponentName(app.packageName, app.backupAgentName)
16625                    : new ComponentName("android", "FullBackupAgent");
16626            // startProcessLocked() returns existing proc's record if it's already running
16627            ProcessRecord proc = startProcessLocked(app.processName, app,
16628                    false, 0, "backup", hostingName, false, false, false);
16629            if (proc == null) {
16630                Slog.e(TAG, "Unable to start backup agent process " + r);
16631                return false;
16632            }
16633
16634            r.app = proc;
16635            mBackupTarget = r;
16636            mBackupAppName = app.packageName;
16637
16638            // Try not to kill the process during backup
16639            updateOomAdjLocked(proc);
16640
16641            // If the process is already attached, schedule the creation of the backup agent now.
16642            // If it is not yet live, this will be done when it attaches to the framework.
16643            if (proc.thread != null) {
16644                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16645                try {
16646                    proc.thread.scheduleCreateBackupAgent(app,
16647                            compatibilityInfoForPackageLocked(app), backupMode);
16648                } catch (RemoteException e) {
16649                    // Will time out on the backup manager side
16650                }
16651            } else {
16652                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16653            }
16654            // Invariants: at this point, the target app process exists and the application
16655            // is either already running or in the process of coming up.  mBackupTarget and
16656            // mBackupAppName describe the app, so that when it binds back to the AM we
16657            // know that it's scheduled for a backup-agent operation.
16658        }
16659
16660        return true;
16661    }
16662
16663    @Override
16664    public void clearPendingBackup() {
16665        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16666        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16667
16668        synchronized (this) {
16669            mBackupTarget = null;
16670            mBackupAppName = null;
16671        }
16672    }
16673
16674    // A backup agent has just come up
16675    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16676        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16677                + " = " + agent);
16678
16679        synchronized(this) {
16680            if (!agentPackageName.equals(mBackupAppName)) {
16681                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16682                return;
16683            }
16684        }
16685
16686        long oldIdent = Binder.clearCallingIdentity();
16687        try {
16688            IBackupManager bm = IBackupManager.Stub.asInterface(
16689                    ServiceManager.getService(Context.BACKUP_SERVICE));
16690            bm.agentConnected(agentPackageName, agent);
16691        } catch (RemoteException e) {
16692            // can't happen; the backup manager service is local
16693        } catch (Exception e) {
16694            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16695            e.printStackTrace();
16696        } finally {
16697            Binder.restoreCallingIdentity(oldIdent);
16698        }
16699    }
16700
16701    // done with this agent
16702    public void unbindBackupAgent(ApplicationInfo appInfo) {
16703        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16704        if (appInfo == null) {
16705            Slog.w(TAG, "unbind backup agent for null app");
16706            return;
16707        }
16708
16709        synchronized(this) {
16710            try {
16711                if (mBackupAppName == null) {
16712                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16713                    return;
16714                }
16715
16716                if (!mBackupAppName.equals(appInfo.packageName)) {
16717                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16718                    return;
16719                }
16720
16721                // Not backing this app up any more; reset its OOM adjustment
16722                final ProcessRecord proc = mBackupTarget.app;
16723                updateOomAdjLocked(proc);
16724
16725                // If the app crashed during backup, 'thread' will be null here
16726                if (proc.thread != null) {
16727                    try {
16728                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16729                                compatibilityInfoForPackageLocked(appInfo));
16730                    } catch (Exception e) {
16731                        Slog.e(TAG, "Exception when unbinding backup agent:");
16732                        e.printStackTrace();
16733                    }
16734                }
16735            } finally {
16736                mBackupTarget = null;
16737                mBackupAppName = null;
16738            }
16739        }
16740    }
16741    // =========================================================
16742    // BROADCASTS
16743    // =========================================================
16744
16745    boolean isPendingBroadcastProcessLocked(int pid) {
16746        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16747                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16748    }
16749
16750    void skipPendingBroadcastLocked(int pid) {
16751            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16752            for (BroadcastQueue queue : mBroadcastQueues) {
16753                queue.skipPendingBroadcastLocked(pid);
16754            }
16755    }
16756
16757    // The app just attached; send any pending broadcasts that it should receive
16758    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16759        boolean didSomething = false;
16760        for (BroadcastQueue queue : mBroadcastQueues) {
16761            didSomething |= queue.sendPendingBroadcastsLocked(app);
16762        }
16763        return didSomething;
16764    }
16765
16766    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16767            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16768        enforceNotIsolatedCaller("registerReceiver");
16769        ArrayList<Intent> stickyIntents = null;
16770        ProcessRecord callerApp = null;
16771        int callingUid;
16772        int callingPid;
16773        synchronized(this) {
16774            if (caller != null) {
16775                callerApp = getRecordForAppLocked(caller);
16776                if (callerApp == null) {
16777                    throw new SecurityException(
16778                            "Unable to find app for caller " + caller
16779                            + " (pid=" + Binder.getCallingPid()
16780                            + ") when registering receiver " + receiver);
16781                }
16782                if (callerApp.info.uid != Process.SYSTEM_UID &&
16783                        !callerApp.pkgList.containsKey(callerPackage) &&
16784                        !"android".equals(callerPackage)) {
16785                    throw new SecurityException("Given caller package " + callerPackage
16786                            + " is not running in process " + callerApp);
16787                }
16788                callingUid = callerApp.info.uid;
16789                callingPid = callerApp.pid;
16790            } else {
16791                callerPackage = null;
16792                callingUid = Binder.getCallingUid();
16793                callingPid = Binder.getCallingPid();
16794            }
16795
16796            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16797                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16798
16799            Iterator<String> actions = filter.actionsIterator();
16800            if (actions == null) {
16801                ArrayList<String> noAction = new ArrayList<String>(1);
16802                noAction.add(null);
16803                actions = noAction.iterator();
16804            }
16805
16806            // Collect stickies of users
16807            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16808            while (actions.hasNext()) {
16809                String action = actions.next();
16810                for (int id : userIds) {
16811                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16812                    if (stickies != null) {
16813                        ArrayList<Intent> intents = stickies.get(action);
16814                        if (intents != null) {
16815                            if (stickyIntents == null) {
16816                                stickyIntents = new ArrayList<Intent>();
16817                            }
16818                            stickyIntents.addAll(intents);
16819                        }
16820                    }
16821                }
16822            }
16823        }
16824
16825        ArrayList<Intent> allSticky = null;
16826        if (stickyIntents != null) {
16827            final ContentResolver resolver = mContext.getContentResolver();
16828            // Look for any matching sticky broadcasts...
16829            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16830                Intent intent = stickyIntents.get(i);
16831                // If intent has scheme "content", it will need to acccess
16832                // provider that needs to lock mProviderMap in ActivityThread
16833                // and also it may need to wait application response, so we
16834                // cannot lock ActivityManagerService here.
16835                if (filter.match(resolver, intent, true, TAG) >= 0) {
16836                    if (allSticky == null) {
16837                        allSticky = new ArrayList<Intent>();
16838                    }
16839                    allSticky.add(intent);
16840                }
16841            }
16842        }
16843
16844        // The first sticky in the list is returned directly back to the client.
16845        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16846        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16847        if (receiver == null) {
16848            return sticky;
16849        }
16850
16851        synchronized (this) {
16852            if (callerApp != null && (callerApp.thread == null
16853                    || callerApp.thread.asBinder() != caller.asBinder())) {
16854                // Original caller already died
16855                return null;
16856            }
16857            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16858            if (rl == null) {
16859                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16860                        userId, receiver);
16861                if (rl.app != null) {
16862                    rl.app.receivers.add(rl);
16863                } else {
16864                    try {
16865                        receiver.asBinder().linkToDeath(rl, 0);
16866                    } catch (RemoteException e) {
16867                        return sticky;
16868                    }
16869                    rl.linkedToDeath = true;
16870                }
16871                mRegisteredReceivers.put(receiver.asBinder(), rl);
16872            } else if (rl.uid != callingUid) {
16873                throw new IllegalArgumentException(
16874                        "Receiver requested to register for uid " + callingUid
16875                        + " was previously registered for uid " + rl.uid);
16876            } else if (rl.pid != callingPid) {
16877                throw new IllegalArgumentException(
16878                        "Receiver requested to register for pid " + callingPid
16879                        + " was previously registered for pid " + rl.pid);
16880            } else if (rl.userId != userId) {
16881                throw new IllegalArgumentException(
16882                        "Receiver requested to register for user " + userId
16883                        + " was previously registered for user " + rl.userId);
16884            }
16885            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16886                    permission, callingUid, userId);
16887            rl.add(bf);
16888            if (!bf.debugCheck()) {
16889                Slog.w(TAG, "==> For Dynamic broadcast");
16890            }
16891            mReceiverResolver.addFilter(bf);
16892
16893            // Enqueue broadcasts for all existing stickies that match
16894            // this filter.
16895            if (allSticky != null) {
16896                ArrayList receivers = new ArrayList();
16897                receivers.add(bf);
16898
16899                final int stickyCount = allSticky.size();
16900                for (int i = 0; i < stickyCount; i++) {
16901                    Intent intent = allSticky.get(i);
16902                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16903                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16904                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16905                            null, 0, null, null, false, true, true, -1);
16906                    queue.enqueueParallelBroadcastLocked(r);
16907                    queue.scheduleBroadcastsLocked();
16908                }
16909            }
16910
16911            return sticky;
16912        }
16913    }
16914
16915    public void unregisterReceiver(IIntentReceiver receiver) {
16916        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16917
16918        final long origId = Binder.clearCallingIdentity();
16919        try {
16920            boolean doTrim = false;
16921
16922            synchronized(this) {
16923                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16924                if (rl != null) {
16925                    final BroadcastRecord r = rl.curBroadcast;
16926                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16927                        final boolean doNext = r.queue.finishReceiverLocked(
16928                                r, r.resultCode, r.resultData, r.resultExtras,
16929                                r.resultAbort, false);
16930                        if (doNext) {
16931                            doTrim = true;
16932                            r.queue.processNextBroadcast(false);
16933                        }
16934                    }
16935
16936                    if (rl.app != null) {
16937                        rl.app.receivers.remove(rl);
16938                    }
16939                    removeReceiverLocked(rl);
16940                    if (rl.linkedToDeath) {
16941                        rl.linkedToDeath = false;
16942                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16943                    }
16944                }
16945            }
16946
16947            // If we actually concluded any broadcasts, we might now be able
16948            // to trim the recipients' apps from our working set
16949            if (doTrim) {
16950                trimApplications();
16951                return;
16952            }
16953
16954        } finally {
16955            Binder.restoreCallingIdentity(origId);
16956        }
16957    }
16958
16959    void removeReceiverLocked(ReceiverList rl) {
16960        mRegisteredReceivers.remove(rl.receiver.asBinder());
16961        for (int i = rl.size() - 1; i >= 0; i--) {
16962            mReceiverResolver.removeFilter(rl.get(i));
16963        }
16964    }
16965
16966    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16967        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16968            ProcessRecord r = mLruProcesses.get(i);
16969            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16970                try {
16971                    r.thread.dispatchPackageBroadcast(cmd, packages);
16972                } catch (RemoteException ex) {
16973                }
16974            }
16975        }
16976    }
16977
16978    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16979            int callingUid, int[] users) {
16980        // TODO: come back and remove this assumption to triage all broadcasts
16981        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16982
16983        List<ResolveInfo> receivers = null;
16984        try {
16985            HashSet<ComponentName> singleUserReceivers = null;
16986            boolean scannedFirstReceivers = false;
16987            for (int user : users) {
16988                // Skip users that have Shell restrictions, with exception of always permitted
16989                // Shell broadcasts
16990                if (callingUid == Process.SHELL_UID
16991                        && mUserController.hasUserRestriction(
16992                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16993                        && !isPermittedShellBroadcast(intent)) {
16994                    continue;
16995                }
16996                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16997                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
16998                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16999                    // If this is not the system user, we need to check for
17000                    // any receivers that should be filtered out.
17001                    for (int i=0; i<newReceivers.size(); i++) {
17002                        ResolveInfo ri = newReceivers.get(i);
17003                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17004                            newReceivers.remove(i);
17005                            i--;
17006                        }
17007                    }
17008                }
17009                if (newReceivers != null && newReceivers.size() == 0) {
17010                    newReceivers = null;
17011                }
17012                if (receivers == null) {
17013                    receivers = newReceivers;
17014                } else if (newReceivers != null) {
17015                    // We need to concatenate the additional receivers
17016                    // found with what we have do far.  This would be easy,
17017                    // but we also need to de-dup any receivers that are
17018                    // singleUser.
17019                    if (!scannedFirstReceivers) {
17020                        // Collect any single user receivers we had already retrieved.
17021                        scannedFirstReceivers = true;
17022                        for (int i=0; i<receivers.size(); i++) {
17023                            ResolveInfo ri = receivers.get(i);
17024                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17025                                ComponentName cn = new ComponentName(
17026                                        ri.activityInfo.packageName, ri.activityInfo.name);
17027                                if (singleUserReceivers == null) {
17028                                    singleUserReceivers = new HashSet<ComponentName>();
17029                                }
17030                                singleUserReceivers.add(cn);
17031                            }
17032                        }
17033                    }
17034                    // Add the new results to the existing results, tracking
17035                    // and de-dupping single user receivers.
17036                    for (int i=0; i<newReceivers.size(); i++) {
17037                        ResolveInfo ri = newReceivers.get(i);
17038                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17039                            ComponentName cn = new ComponentName(
17040                                    ri.activityInfo.packageName, ri.activityInfo.name);
17041                            if (singleUserReceivers == null) {
17042                                singleUserReceivers = new HashSet<ComponentName>();
17043                            }
17044                            if (!singleUserReceivers.contains(cn)) {
17045                                singleUserReceivers.add(cn);
17046                                receivers.add(ri);
17047                            }
17048                        } else {
17049                            receivers.add(ri);
17050                        }
17051                    }
17052                }
17053            }
17054        } catch (RemoteException ex) {
17055            // pm is in same process, this will never happen.
17056        }
17057        return receivers;
17058    }
17059
17060    private boolean isPermittedShellBroadcast(Intent intent) {
17061        // remote bugreport should always be allowed to be taken
17062        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17063    }
17064
17065    final int broadcastIntentLocked(ProcessRecord callerApp,
17066            String callerPackage, Intent intent, String resolvedType,
17067            IIntentReceiver resultTo, int resultCode, String resultData,
17068            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17069            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17070        intent = new Intent(intent);
17071
17072        // By default broadcasts do not go to stopped apps.
17073        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17074
17075        // If we have not finished booting, don't allow this to launch new processes.
17076        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17077            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17078        }
17079
17080        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17081                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17082                + " ordered=" + ordered + " userid=" + userId);
17083        if ((resultTo != null) && !ordered) {
17084            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17085        }
17086
17087        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17088                ALLOW_NON_FULL, "broadcast", callerPackage);
17089
17090        // Make sure that the user who is receiving this broadcast is running.
17091        // If not, we will just skip it. Make an exception for shutdown broadcasts
17092        // and upgrade steps.
17093
17094        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17095            if ((callingUid != Process.SYSTEM_UID
17096                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17097                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17098                Slog.w(TAG, "Skipping broadcast of " + intent
17099                        + ": user " + userId + " is stopped");
17100                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17101            }
17102        }
17103
17104        BroadcastOptions brOptions = null;
17105        if (bOptions != null) {
17106            brOptions = new BroadcastOptions(bOptions);
17107            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17108                // See if the caller is allowed to do this.  Note we are checking against
17109                // the actual real caller (not whoever provided the operation as say a
17110                // PendingIntent), because that who is actually supplied the arguments.
17111                if (checkComponentPermission(
17112                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17113                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17114                        != PackageManager.PERMISSION_GRANTED) {
17115                    String msg = "Permission Denial: " + intent.getAction()
17116                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17117                            + ", uid=" + callingUid + ")"
17118                            + " requires "
17119                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17120                    Slog.w(TAG, msg);
17121                    throw new SecurityException(msg);
17122                }
17123            }
17124        }
17125
17126        // Verify that protected broadcasts are only being sent by system code,
17127        // and that system code is only sending protected broadcasts.
17128        final String action = intent.getAction();
17129        final boolean isProtectedBroadcast;
17130        try {
17131            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17132        } catch (RemoteException e) {
17133            Slog.w(TAG, "Remote exception", e);
17134            return ActivityManager.BROADCAST_SUCCESS;
17135        }
17136
17137        final boolean isCallerSystem;
17138        switch (UserHandle.getAppId(callingUid)) {
17139            case Process.ROOT_UID:
17140            case Process.SYSTEM_UID:
17141            case Process.PHONE_UID:
17142            case Process.BLUETOOTH_UID:
17143            case Process.NFC_UID:
17144                isCallerSystem = true;
17145                break;
17146            default:
17147                isCallerSystem = (callerApp != null) && callerApp.persistent;
17148                break;
17149        }
17150
17151        if (isCallerSystem) {
17152            if (isProtectedBroadcast
17153                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17154                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17155                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17156                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17157                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17158                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17159                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17160                // Broadcast is either protected, or it's a public action that
17161                // we've relaxed, so it's fine for system internals to send.
17162            } else {
17163                // The vast majority of broadcasts sent from system internals
17164                // should be protected to avoid security holes, so yell loudly
17165                // to ensure we examine these cases.
17166                Log.wtf(TAG, "Sending non-protected broadcast " + action
17167                        + " from system", new Throwable());
17168            }
17169
17170        } else {
17171            if (isProtectedBroadcast) {
17172                String msg = "Permission Denial: not allowed to send broadcast "
17173                        + action + " from pid="
17174                        + callingPid + ", uid=" + callingUid;
17175                Slog.w(TAG, msg);
17176                throw new SecurityException(msg);
17177
17178            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17179                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17180                // Special case for compatibility: we don't want apps to send this,
17181                // but historically it has not been protected and apps may be using it
17182                // to poke their own app widget.  So, instead of making it protected,
17183                // just limit it to the caller.
17184                if (callerPackage == null) {
17185                    String msg = "Permission Denial: not allowed to send broadcast "
17186                            + action + " from unknown caller.";
17187                    Slog.w(TAG, msg);
17188                    throw new SecurityException(msg);
17189                } else if (intent.getComponent() != null) {
17190                    // They are good enough to send to an explicit component...  verify
17191                    // it is being sent to the calling app.
17192                    if (!intent.getComponent().getPackageName().equals(
17193                            callerPackage)) {
17194                        String msg = "Permission Denial: not allowed to send broadcast "
17195                                + action + " to "
17196                                + intent.getComponent().getPackageName() + " from "
17197                                + callerPackage;
17198                        Slog.w(TAG, msg);
17199                        throw new SecurityException(msg);
17200                    }
17201                } else {
17202                    // Limit broadcast to their own package.
17203                    intent.setPackage(callerPackage);
17204                }
17205            }
17206        }
17207
17208        if (action != null) {
17209            switch (action) {
17210                case Intent.ACTION_UID_REMOVED:
17211                case Intent.ACTION_PACKAGE_REMOVED:
17212                case Intent.ACTION_PACKAGE_CHANGED:
17213                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17214                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17215                case Intent.ACTION_PACKAGES_SUSPENDED:
17216                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17217                    // Handle special intents: if this broadcast is from the package
17218                    // manager about a package being removed, we need to remove all of
17219                    // its activities from the history stack.
17220                    if (checkComponentPermission(
17221                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17222                            callingPid, callingUid, -1, true)
17223                            != PackageManager.PERMISSION_GRANTED) {
17224                        String msg = "Permission Denial: " + intent.getAction()
17225                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17226                                + ", uid=" + callingUid + ")"
17227                                + " requires "
17228                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17229                        Slog.w(TAG, msg);
17230                        throw new SecurityException(msg);
17231                    }
17232                    switch (action) {
17233                        case Intent.ACTION_UID_REMOVED:
17234                            final Bundle intentExtras = intent.getExtras();
17235                            final int uid = intentExtras != null
17236                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17237                            if (uid >= 0) {
17238                                mBatteryStatsService.removeUid(uid);
17239                                mAppOpsService.uidRemoved(uid);
17240                            }
17241                            break;
17242                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17243                            // If resources are unavailable just force stop all those packages
17244                            // and flush the attribute cache as well.
17245                            String list[] =
17246                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17247                            if (list != null && list.length > 0) {
17248                                for (int i = 0; i < list.length; i++) {
17249                                    forceStopPackageLocked(list[i], -1, false, true, true,
17250                                            false, false, userId, "storage unmount");
17251                                }
17252                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17253                                sendPackageBroadcastLocked(
17254                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17255                                        userId);
17256                            }
17257                            break;
17258                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17259                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17260                            break;
17261                        case Intent.ACTION_PACKAGE_REMOVED:
17262                        case Intent.ACTION_PACKAGE_CHANGED:
17263                            Uri data = intent.getData();
17264                            String ssp;
17265                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17266                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17267                                final boolean replacing =
17268                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17269                                final boolean killProcess =
17270                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17271                                final boolean fullUninstall = removed && !replacing;
17272                                if (killProcess) {
17273                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17274                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17275                                            false, true, true, false, fullUninstall, userId,
17276                                            removed ? "pkg removed" : "pkg changed");
17277                                }
17278                                if (removed) {
17279                                    final int cmd = killProcess
17280                                            ? IApplicationThread.PACKAGE_REMOVED
17281                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17282                                    sendPackageBroadcastLocked(cmd,
17283                                            new String[] {ssp}, userId);
17284                                    if (fullUninstall) {
17285                                        mAppOpsService.packageRemoved(
17286                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17287
17288                                        // Remove all permissions granted from/to this package
17289                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17290
17291                                        removeTasksByPackageNameLocked(ssp, userId);
17292                                        mBatteryStatsService.notePackageUninstalled(ssp);
17293                                    }
17294                                } else {
17295                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17296                                            intent.getStringArrayExtra(
17297                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17298                                }
17299                            }
17300                            break;
17301                        case Intent.ACTION_PACKAGES_SUSPENDED:
17302                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17303                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17304                                    intent.getAction());
17305                            final String[] packageNames = intent.getStringArrayExtra(
17306                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17307                            final int userHandle = intent.getIntExtra(
17308                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17309
17310                            synchronized(ActivityManagerService.this) {
17311                                mRecentTasks.onPackagesSuspendedChanged(
17312                                        packageNames, suspended, userHandle);
17313                            }
17314                            break;
17315                    }
17316                    break;
17317                case Intent.ACTION_PACKAGE_REPLACED:
17318                {
17319                    final Uri data = intent.getData();
17320                    final String ssp;
17321                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17322                        final ApplicationInfo aInfo =
17323                                getPackageManagerInternalLocked().getApplicationInfo(
17324                                        ssp,
17325                                        userId);
17326                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17327                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17328                                new String[] {ssp}, userId);
17329                    }
17330                    break;
17331                }
17332                case Intent.ACTION_PACKAGE_ADDED:
17333                {
17334                    // Special case for adding a package: by default turn on compatibility mode.
17335                    Uri data = intent.getData();
17336                    String ssp;
17337                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17338                        final boolean replacing =
17339                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17340                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17341
17342                        try {
17343                            ApplicationInfo ai = AppGlobals.getPackageManager().
17344                                    getApplicationInfo(ssp, 0, 0);
17345                            mBatteryStatsService.notePackageInstalled(ssp,
17346                                    ai != null ? ai.versionCode : 0);
17347                        } catch (RemoteException e) {
17348                        }
17349                    }
17350                    break;
17351                }
17352                case Intent.ACTION_TIMEZONE_CHANGED:
17353                    // If this is the time zone changed action, queue up a message that will reset
17354                    // the timezone of all currently running processes. This message will get
17355                    // queued up before the broadcast happens.
17356                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17357                    break;
17358                case Intent.ACTION_TIME_CHANGED:
17359                    // If the user set the time, let all running processes know.
17360                    final int is24Hour =
17361                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17362                                    : 0;
17363                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17364                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17365                    synchronized (stats) {
17366                        stats.noteCurrentTimeChangedLocked();
17367                    }
17368                    break;
17369                case Intent.ACTION_CLEAR_DNS_CACHE:
17370                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17371                    break;
17372                case Proxy.PROXY_CHANGE_ACTION:
17373                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17374                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17375                    break;
17376                case android.hardware.Camera.ACTION_NEW_PICTURE:
17377                case android.hardware.Camera.ACTION_NEW_VIDEO:
17378                    // These broadcasts are no longer allowed by the system, since they can
17379                    // cause significant thrashing at a crictical point (using the camera).
17380                    // Apps should use JobScehduler to monitor for media provider changes.
17381                    Slog.w(TAG, action + " no longer allowed; dropping from "
17382                            + UserHandle.formatUid(callingUid));
17383                    // Lie; we don't want to crash the app.
17384                    return ActivityManager.BROADCAST_SUCCESS;
17385            }
17386        }
17387
17388        // Add to the sticky list if requested.
17389        if (sticky) {
17390            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17391                    callingPid, callingUid)
17392                    != PackageManager.PERMISSION_GRANTED) {
17393                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17394                        + callingPid + ", uid=" + callingUid
17395                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17396                Slog.w(TAG, msg);
17397                throw new SecurityException(msg);
17398            }
17399            if (requiredPermissions != null && requiredPermissions.length > 0) {
17400                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17401                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17402                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17403            }
17404            if (intent.getComponent() != null) {
17405                throw new SecurityException(
17406                        "Sticky broadcasts can't target a specific component");
17407            }
17408            // We use userId directly here, since the "all" target is maintained
17409            // as a separate set of sticky broadcasts.
17410            if (userId != UserHandle.USER_ALL) {
17411                // But first, if this is not a broadcast to all users, then
17412                // make sure it doesn't conflict with an existing broadcast to
17413                // all users.
17414                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17415                        UserHandle.USER_ALL);
17416                if (stickies != null) {
17417                    ArrayList<Intent> list = stickies.get(intent.getAction());
17418                    if (list != null) {
17419                        int N = list.size();
17420                        int i;
17421                        for (i=0; i<N; i++) {
17422                            if (intent.filterEquals(list.get(i))) {
17423                                throw new IllegalArgumentException(
17424                                        "Sticky broadcast " + intent + " for user "
17425                                        + userId + " conflicts with existing global broadcast");
17426                            }
17427                        }
17428                    }
17429                }
17430            }
17431            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17432            if (stickies == null) {
17433                stickies = new ArrayMap<>();
17434                mStickyBroadcasts.put(userId, stickies);
17435            }
17436            ArrayList<Intent> list = stickies.get(intent.getAction());
17437            if (list == null) {
17438                list = new ArrayList<>();
17439                stickies.put(intent.getAction(), list);
17440            }
17441            final int stickiesCount = list.size();
17442            int i;
17443            for (i = 0; i < stickiesCount; i++) {
17444                if (intent.filterEquals(list.get(i))) {
17445                    // This sticky already exists, replace it.
17446                    list.set(i, new Intent(intent));
17447                    break;
17448                }
17449            }
17450            if (i >= stickiesCount) {
17451                list.add(new Intent(intent));
17452            }
17453        }
17454
17455        int[] users;
17456        if (userId == UserHandle.USER_ALL) {
17457            // Caller wants broadcast to go to all started users.
17458            users = mUserController.getStartedUserArrayLocked();
17459        } else {
17460            // Caller wants broadcast to go to one specific user.
17461            users = new int[] {userId};
17462        }
17463
17464        // Figure out who all will receive this broadcast.
17465        List receivers = null;
17466        List<BroadcastFilter> registeredReceivers = null;
17467        // Need to resolve the intent to interested receivers...
17468        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17469                 == 0) {
17470            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17471        }
17472        if (intent.getComponent() == null) {
17473            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17474                // Query one target user at a time, excluding shell-restricted users
17475                for (int i = 0; i < users.length; i++) {
17476                    if (mUserController.hasUserRestriction(
17477                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17478                        continue;
17479                    }
17480                    List<BroadcastFilter> registeredReceiversForUser =
17481                            mReceiverResolver.queryIntent(intent,
17482                                    resolvedType, false, users[i]);
17483                    if (registeredReceivers == null) {
17484                        registeredReceivers = registeredReceiversForUser;
17485                    } else if (registeredReceiversForUser != null) {
17486                        registeredReceivers.addAll(registeredReceiversForUser);
17487                    }
17488                }
17489            } else {
17490                registeredReceivers = mReceiverResolver.queryIntent(intent,
17491                        resolvedType, false, userId);
17492            }
17493        }
17494
17495        final boolean replacePending =
17496                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17497
17498        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17499                + " replacePending=" + replacePending);
17500
17501        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17502        if (!ordered && NR > 0) {
17503            // If we are not serializing this broadcast, then send the
17504            // registered receivers separately so they don't wait for the
17505            // components to be launched.
17506            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17507            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17508                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17509                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17510                    resultExtras, ordered, sticky, false, userId);
17511            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17512            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17513            if (!replaced) {
17514                queue.enqueueParallelBroadcastLocked(r);
17515                queue.scheduleBroadcastsLocked();
17516            }
17517            registeredReceivers = null;
17518            NR = 0;
17519        }
17520
17521        // Merge into one list.
17522        int ir = 0;
17523        if (receivers != null) {
17524            // A special case for PACKAGE_ADDED: do not allow the package
17525            // being added to see this broadcast.  This prevents them from
17526            // using this as a back door to get run as soon as they are
17527            // installed.  Maybe in the future we want to have a special install
17528            // broadcast or such for apps, but we'd like to deliberately make
17529            // this decision.
17530            String skipPackages[] = null;
17531            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17532                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17533                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17534                Uri data = intent.getData();
17535                if (data != null) {
17536                    String pkgName = data.getSchemeSpecificPart();
17537                    if (pkgName != null) {
17538                        skipPackages = new String[] { pkgName };
17539                    }
17540                }
17541            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17542                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17543            }
17544            if (skipPackages != null && (skipPackages.length > 0)) {
17545                for (String skipPackage : skipPackages) {
17546                    if (skipPackage != null) {
17547                        int NT = receivers.size();
17548                        for (int it=0; it<NT; it++) {
17549                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17550                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17551                                receivers.remove(it);
17552                                it--;
17553                                NT--;
17554                            }
17555                        }
17556                    }
17557                }
17558            }
17559
17560            int NT = receivers != null ? receivers.size() : 0;
17561            int it = 0;
17562            ResolveInfo curt = null;
17563            BroadcastFilter curr = null;
17564            while (it < NT && ir < NR) {
17565                if (curt == null) {
17566                    curt = (ResolveInfo)receivers.get(it);
17567                }
17568                if (curr == null) {
17569                    curr = registeredReceivers.get(ir);
17570                }
17571                if (curr.getPriority() >= curt.priority) {
17572                    // Insert this broadcast record into the final list.
17573                    receivers.add(it, curr);
17574                    ir++;
17575                    curr = null;
17576                    it++;
17577                    NT++;
17578                } else {
17579                    // Skip to the next ResolveInfo in the final list.
17580                    it++;
17581                    curt = null;
17582                }
17583            }
17584        }
17585        while (ir < NR) {
17586            if (receivers == null) {
17587                receivers = new ArrayList();
17588            }
17589            receivers.add(registeredReceivers.get(ir));
17590            ir++;
17591        }
17592
17593        if ((receivers != null && receivers.size() > 0)
17594                || resultTo != null) {
17595            BroadcastQueue queue = broadcastQueueForIntent(intent);
17596            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17597                    callerPackage, callingPid, callingUid, resolvedType,
17598                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17599                    resultData, resultExtras, ordered, sticky, false, userId);
17600
17601            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17602                    + ": prev had " + queue.mOrderedBroadcasts.size());
17603            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17604                    "Enqueueing broadcast " + r.intent.getAction());
17605
17606            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17607            if (!replaced) {
17608                queue.enqueueOrderedBroadcastLocked(r);
17609                queue.scheduleBroadcastsLocked();
17610            }
17611        }
17612
17613        return ActivityManager.BROADCAST_SUCCESS;
17614    }
17615
17616    final Intent verifyBroadcastLocked(Intent intent) {
17617        // Refuse possible leaked file descriptors
17618        if (intent != null && intent.hasFileDescriptors() == true) {
17619            throw new IllegalArgumentException("File descriptors passed in Intent");
17620        }
17621
17622        int flags = intent.getFlags();
17623
17624        if (!mProcessesReady) {
17625            // if the caller really truly claims to know what they're doing, go
17626            // ahead and allow the broadcast without launching any receivers
17627            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17628                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17629            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17630                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17631                        + " before boot completion");
17632                throw new IllegalStateException("Cannot broadcast before boot completed");
17633            }
17634        }
17635
17636        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17637            throw new IllegalArgumentException(
17638                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17639        }
17640
17641        return intent;
17642    }
17643
17644    public final int broadcastIntent(IApplicationThread caller,
17645            Intent intent, String resolvedType, IIntentReceiver resultTo,
17646            int resultCode, String resultData, Bundle resultExtras,
17647            String[] requiredPermissions, int appOp, Bundle bOptions,
17648            boolean serialized, boolean sticky, int userId) {
17649        enforceNotIsolatedCaller("broadcastIntent");
17650        synchronized(this) {
17651            intent = verifyBroadcastLocked(intent);
17652
17653            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17654            final int callingPid = Binder.getCallingPid();
17655            final int callingUid = Binder.getCallingUid();
17656            final long origId = Binder.clearCallingIdentity();
17657            int res = broadcastIntentLocked(callerApp,
17658                    callerApp != null ? callerApp.info.packageName : null,
17659                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17660                    requiredPermissions, appOp, bOptions, serialized, sticky,
17661                    callingPid, callingUid, userId);
17662            Binder.restoreCallingIdentity(origId);
17663            return res;
17664        }
17665    }
17666
17667
17668    int broadcastIntentInPackage(String packageName, int uid,
17669            Intent intent, String resolvedType, IIntentReceiver resultTo,
17670            int resultCode, String resultData, Bundle resultExtras,
17671            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17672            int userId) {
17673        synchronized(this) {
17674            intent = verifyBroadcastLocked(intent);
17675
17676            final long origId = Binder.clearCallingIdentity();
17677            String[] requiredPermissions = requiredPermission == null ? null
17678                    : new String[] {requiredPermission};
17679            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17680                    resultTo, resultCode, resultData, resultExtras,
17681                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17682                    sticky, -1, uid, userId);
17683            Binder.restoreCallingIdentity(origId);
17684            return res;
17685        }
17686    }
17687
17688    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17689        // Refuse possible leaked file descriptors
17690        if (intent != null && intent.hasFileDescriptors() == true) {
17691            throw new IllegalArgumentException("File descriptors passed in Intent");
17692        }
17693
17694        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17695                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17696
17697        synchronized(this) {
17698            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17699                    != PackageManager.PERMISSION_GRANTED) {
17700                String msg = "Permission Denial: unbroadcastIntent() from pid="
17701                        + Binder.getCallingPid()
17702                        + ", uid=" + Binder.getCallingUid()
17703                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17704                Slog.w(TAG, msg);
17705                throw new SecurityException(msg);
17706            }
17707            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17708            if (stickies != null) {
17709                ArrayList<Intent> list = stickies.get(intent.getAction());
17710                if (list != null) {
17711                    int N = list.size();
17712                    int i;
17713                    for (i=0; i<N; i++) {
17714                        if (intent.filterEquals(list.get(i))) {
17715                            list.remove(i);
17716                            break;
17717                        }
17718                    }
17719                    if (list.size() <= 0) {
17720                        stickies.remove(intent.getAction());
17721                    }
17722                }
17723                if (stickies.size() <= 0) {
17724                    mStickyBroadcasts.remove(userId);
17725                }
17726            }
17727        }
17728    }
17729
17730    void backgroundServicesFinishedLocked(int userId) {
17731        for (BroadcastQueue queue : mBroadcastQueues) {
17732            queue.backgroundServicesFinishedLocked(userId);
17733        }
17734    }
17735
17736    public void finishReceiver(IBinder who, int resultCode, String resultData,
17737            Bundle resultExtras, boolean resultAbort, int flags) {
17738        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17739
17740        // Refuse possible leaked file descriptors
17741        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17742            throw new IllegalArgumentException("File descriptors passed in Bundle");
17743        }
17744
17745        final long origId = Binder.clearCallingIdentity();
17746        try {
17747            boolean doNext = false;
17748            BroadcastRecord r;
17749
17750            synchronized(this) {
17751                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17752                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17753                r = queue.getMatchingOrderedReceiver(who);
17754                if (r != null) {
17755                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17756                        resultData, resultExtras, resultAbort, true);
17757                }
17758            }
17759
17760            if (doNext) {
17761                r.queue.processNextBroadcast(false);
17762            }
17763            trimApplications();
17764        } finally {
17765            Binder.restoreCallingIdentity(origId);
17766        }
17767    }
17768
17769    // =========================================================
17770    // INSTRUMENTATION
17771    // =========================================================
17772
17773    public boolean startInstrumentation(ComponentName className,
17774            String profileFile, int flags, Bundle arguments,
17775            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17776            int userId, String abiOverride) {
17777        enforceNotIsolatedCaller("startInstrumentation");
17778        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17779                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17780        // Refuse possible leaked file descriptors
17781        if (arguments != null && arguments.hasFileDescriptors()) {
17782            throw new IllegalArgumentException("File descriptors passed in Bundle");
17783        }
17784
17785        synchronized(this) {
17786            InstrumentationInfo ii = null;
17787            ApplicationInfo ai = null;
17788            try {
17789                ii = mContext.getPackageManager().getInstrumentationInfo(
17790                    className, STOCK_PM_FLAGS);
17791                ai = AppGlobals.getPackageManager().getApplicationInfo(
17792                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17793            } catch (PackageManager.NameNotFoundException e) {
17794            } catch (RemoteException e) {
17795            }
17796            if (ii == null) {
17797                reportStartInstrumentationFailureLocked(watcher, className,
17798                        "Unable to find instrumentation info for: " + className);
17799                return false;
17800            }
17801            if (ai == null) {
17802                reportStartInstrumentationFailureLocked(watcher, className,
17803                        "Unable to find instrumentation target package: " + ii.targetPackage);
17804                return false;
17805            }
17806            if (!ai.hasCode()) {
17807                reportStartInstrumentationFailureLocked(watcher, className,
17808                        "Instrumentation target has no code: " + ii.targetPackage);
17809                return false;
17810            }
17811
17812            int match = mContext.getPackageManager().checkSignatures(
17813                    ii.targetPackage, ii.packageName);
17814            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17815                String msg = "Permission Denial: starting instrumentation "
17816                        + className + " from pid="
17817                        + Binder.getCallingPid()
17818                        + ", uid=" + Binder.getCallingPid()
17819                        + " not allowed because package " + ii.packageName
17820                        + " does not have a signature matching the target "
17821                        + ii.targetPackage;
17822                reportStartInstrumentationFailureLocked(watcher, className, msg);
17823                throw new SecurityException(msg);
17824            }
17825
17826            final long origId = Binder.clearCallingIdentity();
17827            // Instrumentation can kill and relaunch even persistent processes
17828            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17829                    "start instr");
17830            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17831            app.instrumentationClass = className;
17832            app.instrumentationInfo = ai;
17833            app.instrumentationProfileFile = profileFile;
17834            app.instrumentationArguments = arguments;
17835            app.instrumentationWatcher = watcher;
17836            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17837            app.instrumentationResultClass = className;
17838            Binder.restoreCallingIdentity(origId);
17839        }
17840
17841        return true;
17842    }
17843
17844    /**
17845     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17846     * error to the logs, but if somebody is watching, send the report there too.  This enables
17847     * the "am" command to report errors with more information.
17848     *
17849     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17850     * @param cn The component name of the instrumentation.
17851     * @param report The error report.
17852     */
17853    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17854            ComponentName cn, String report) {
17855        Slog.w(TAG, report);
17856        if (watcher != null) {
17857            Bundle results = new Bundle();
17858            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17859            results.putString("Error", report);
17860            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17861        }
17862    }
17863
17864    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17865        if (app.instrumentationWatcher != null) {
17866            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17867                    app.instrumentationClass, resultCode, results);
17868        }
17869
17870        // Can't call out of the system process with a lock held, so post a message.
17871        if (app.instrumentationUiAutomationConnection != null) {
17872            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17873                    app.instrumentationUiAutomationConnection).sendToTarget();
17874        }
17875
17876        app.instrumentationWatcher = null;
17877        app.instrumentationUiAutomationConnection = null;
17878        app.instrumentationClass = null;
17879        app.instrumentationInfo = null;
17880        app.instrumentationProfileFile = null;
17881        app.instrumentationArguments = null;
17882
17883        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17884                "finished inst");
17885    }
17886
17887    public void finishInstrumentation(IApplicationThread target,
17888            int resultCode, Bundle results) {
17889        int userId = UserHandle.getCallingUserId();
17890        // Refuse possible leaked file descriptors
17891        if (results != null && results.hasFileDescriptors()) {
17892            throw new IllegalArgumentException("File descriptors passed in Intent");
17893        }
17894
17895        synchronized(this) {
17896            ProcessRecord app = getRecordForAppLocked(target);
17897            if (app == null) {
17898                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17899                return;
17900            }
17901            final long origId = Binder.clearCallingIdentity();
17902            finishInstrumentationLocked(app, resultCode, results);
17903            Binder.restoreCallingIdentity(origId);
17904        }
17905    }
17906
17907    // =========================================================
17908    // CONFIGURATION
17909    // =========================================================
17910
17911    public ConfigurationInfo getDeviceConfigurationInfo() {
17912        ConfigurationInfo config = new ConfigurationInfo();
17913        synchronized (this) {
17914            config.reqTouchScreen = mConfiguration.touchscreen;
17915            config.reqKeyboardType = mConfiguration.keyboard;
17916            config.reqNavigation = mConfiguration.navigation;
17917            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17918                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17919                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17920            }
17921            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17922                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17923                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17924            }
17925            config.reqGlEsVersion = GL_ES_VERSION;
17926        }
17927        return config;
17928    }
17929
17930    ActivityStack getFocusedStack() {
17931        return mStackSupervisor.getFocusedStack();
17932    }
17933
17934    @Override
17935    public int getFocusedStackId() throws RemoteException {
17936        ActivityStack focusedStack = getFocusedStack();
17937        if (focusedStack != null) {
17938            return focusedStack.getStackId();
17939        }
17940        return -1;
17941    }
17942
17943    public Configuration getConfiguration() {
17944        Configuration ci;
17945        synchronized(this) {
17946            ci = new Configuration(mConfiguration);
17947            ci.userSetLocale = false;
17948        }
17949        return ci;
17950    }
17951
17952    @Override
17953    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17954        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17955        synchronized (this) {
17956            mSuppressResizeConfigChanges = suppress;
17957        }
17958    }
17959
17960    @Override
17961    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17962        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17963        if (fromStackId == HOME_STACK_ID) {
17964            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17965        }
17966        synchronized (this) {
17967            final long origId = Binder.clearCallingIdentity();
17968            try {
17969                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
17970            } finally {
17971                Binder.restoreCallingIdentity(origId);
17972            }
17973        }
17974    }
17975
17976    @Override
17977    public void updatePersistentConfiguration(Configuration values) {
17978        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17979                "updateConfiguration()");
17980        enforceWriteSettingsPermission("updateConfiguration()");
17981        if (values == null) {
17982            throw new NullPointerException("Configuration must not be null");
17983        }
17984
17985        int userId = UserHandle.getCallingUserId();
17986
17987        synchronized(this) {
17988            final long origId = Binder.clearCallingIdentity();
17989            updateConfigurationLocked(values, null, false, true, userId);
17990            Binder.restoreCallingIdentity(origId);
17991        }
17992    }
17993
17994    private void updateFontScaleIfNeeded() {
17995        final int currentUserId;
17996        synchronized(this) {
17997            currentUserId = mUserController.getCurrentUserIdLocked();
17998        }
17999        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18000                FONT_SCALE, 1.0f, currentUserId);
18001        if (mConfiguration.fontScale != scaleFactor) {
18002            final Configuration configuration = mWindowManager.computeNewConfiguration();
18003            configuration.fontScale = scaleFactor;
18004            updatePersistentConfiguration(configuration);
18005        }
18006    }
18007
18008    private void enforceWriteSettingsPermission(String func) {
18009        int uid = Binder.getCallingUid();
18010        if (uid == Process.ROOT_UID) {
18011            return;
18012        }
18013
18014        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18015                Settings.getPackageNameForUid(mContext, uid), false)) {
18016            return;
18017        }
18018
18019        String msg = "Permission Denial: " + func + " from pid="
18020                + Binder.getCallingPid()
18021                + ", uid=" + uid
18022                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18023        Slog.w(TAG, msg);
18024        throw new SecurityException(msg);
18025    }
18026
18027    public void updateConfiguration(Configuration values) {
18028        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18029                "updateConfiguration()");
18030
18031        synchronized(this) {
18032            if (values == null && mWindowManager != null) {
18033                // sentinel: fetch the current configuration from the window manager
18034                values = mWindowManager.computeNewConfiguration();
18035            }
18036
18037            if (mWindowManager != null) {
18038                mProcessList.applyDisplaySize(mWindowManager);
18039            }
18040
18041            final long origId = Binder.clearCallingIdentity();
18042            if (values != null) {
18043                Settings.System.clearConfiguration(values);
18044            }
18045            updateConfigurationLocked(values, null, false);
18046            Binder.restoreCallingIdentity(origId);
18047        }
18048    }
18049
18050    void updateUserConfigurationLocked() {
18051        Configuration configuration = new Configuration(mConfiguration);
18052        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18053                mUserController.getCurrentUserIdLocked());
18054        updateConfigurationLocked(configuration, null, false);
18055    }
18056
18057    boolean updateConfigurationLocked(Configuration values,
18058            ActivityRecord starting, boolean initLocale) {
18059        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18060        return updateConfigurationLocked(values, starting, initLocale, false,
18061                UserHandle.USER_NULL);
18062    }
18063
18064    // To cache the list of supported system locales
18065    private String[] mSupportedSystemLocales = null;
18066
18067    /**
18068     * Do either or both things: (1) change the current configuration, and (2)
18069     * make sure the given activity is running with the (now) current
18070     * configuration.  Returns true if the activity has been left running, or
18071     * false if <var>starting</var> is being destroyed to match the new
18072     * configuration.
18073     *
18074     * @param userId is only used when persistent parameter is set to true to persist configuration
18075     *               for that particular user
18076     */
18077    private boolean updateConfigurationLocked(Configuration values,
18078            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18079        int changes = 0;
18080
18081        if (mWindowManager != null) {
18082            mWindowManager.deferSurfaceLayout();
18083        }
18084        if (values != null) {
18085            Configuration newConfig = new Configuration(mConfiguration);
18086            changes = newConfig.updateFrom(values);
18087            if (changes != 0) {
18088                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18089                        "Updating configuration to: " + values);
18090
18091                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18092
18093                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18094                    final Locale locale;
18095                    if (values.getLocales().size() == 1) {
18096                        // This is an optimization to avoid the JNI call when the result of
18097                        // getFirstMatch() does not depend on the supported locales.
18098                        locale = values.getLocales().get(0);
18099                    } else {
18100                        if (mSupportedSystemLocales == null) {
18101                            mSupportedSystemLocales =
18102                                    Resources.getSystem().getAssets().getLocales();
18103                        }
18104                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18105                    }
18106                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18107                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18108                            locale));
18109                }
18110
18111                mConfigurationSeq++;
18112                if (mConfigurationSeq <= 0) {
18113                    mConfigurationSeq = 1;
18114                }
18115                newConfig.seq = mConfigurationSeq;
18116                mConfiguration = newConfig;
18117                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18118                mUsageStatsService.reportConfigurationChange(newConfig,
18119                        mUserController.getCurrentUserIdLocked());
18120                //mUsageStatsService.noteStartConfig(newConfig);
18121
18122                final Configuration configCopy = new Configuration(mConfiguration);
18123
18124                // TODO: If our config changes, should we auto dismiss any currently
18125                // showing dialogs?
18126                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18127
18128                AttributeCache ac = AttributeCache.instance();
18129                if (ac != null) {
18130                    ac.updateConfiguration(configCopy);
18131                }
18132
18133                // Make sure all resources in our process are updated
18134                // right now, so that anyone who is going to retrieve
18135                // resource values after we return will be sure to get
18136                // the new ones.  This is especially important during
18137                // boot, where the first config change needs to guarantee
18138                // all resources have that config before following boot
18139                // code is executed.
18140                mSystemThread.applyConfigurationToResources(configCopy);
18141
18142                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18143                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18144                    msg.obj = new Configuration(configCopy);
18145                    msg.arg1 = userId;
18146                    mHandler.sendMessage(msg);
18147                }
18148
18149                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18150                if (isDensityChange) {
18151                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18152                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18153                }
18154
18155                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18156                    ProcessRecord app = mLruProcesses.get(i);
18157                    try {
18158                        if (app.thread != null) {
18159                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18160                                    + app.processName + " new config " + mConfiguration);
18161                            app.thread.scheduleConfigurationChanged(configCopy);
18162                        }
18163                    } catch (Exception e) {
18164                    }
18165                }
18166                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18167                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18168                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18169                        | Intent.FLAG_RECEIVER_FOREGROUND);
18170                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18171                        null, AppOpsManager.OP_NONE, null, false, false,
18172                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18173                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18174                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18175                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18176                    if (!mProcessesReady) {
18177                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18178                    }
18179                    broadcastIntentLocked(null, null, intent,
18180                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18181                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18182                }
18183            }
18184            // Update the configuration with WM first and check if any of the stacks need to be
18185            // resized due to the configuration change. If so, resize the stacks now and do any
18186            // relaunches if necessary. This way we don't need to relaunch again below in
18187            // ensureActivityConfigurationLocked().
18188            if (mWindowManager != null) {
18189                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18190                if (resizedStacks != null) {
18191                    for (int stackId : resizedStacks) {
18192                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18193                        mStackSupervisor.resizeStackLocked(
18194                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18195                    }
18196                }
18197            }
18198        }
18199
18200        boolean kept = true;
18201        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18202        // mainStack is null during startup.
18203        if (mainStack != null) {
18204            if (changes != 0 && starting == null) {
18205                // If the configuration changed, and the caller is not already
18206                // in the process of starting an activity, then find the top
18207                // activity to check if its configuration needs to change.
18208                starting = mainStack.topRunningActivityLocked();
18209            }
18210
18211            if (starting != null) {
18212                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18213                // And we need to make sure at this point that all other activities
18214                // are made visible with the correct configuration.
18215                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18216                        !PRESERVE_WINDOWS);
18217            }
18218        }
18219        if (mWindowManager != null) {
18220            mWindowManager.continueSurfaceLayout();
18221        }
18222        return kept;
18223    }
18224
18225    /**
18226     * Decide based on the configuration whether we should shouw the ANR,
18227     * crash, etc dialogs.  The idea is that if there is no affordnace to
18228     * press the on-screen buttons, we shouldn't show the dialog.
18229     *
18230     * A thought: SystemUI might also want to get told about this, the Power
18231     * dialog / global actions also might want different behaviors.
18232     */
18233    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18234        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18235                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18236                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18237        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18238                                    == Configuration.UI_MODE_TYPE_CAR);
18239        return inputMethodExists && uiIsNotCarType && !inVrMode;
18240    }
18241
18242    @Override
18243    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18244        synchronized (this) {
18245            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18246            if (srec != null) {
18247                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18248            }
18249        }
18250        return false;
18251    }
18252
18253    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18254            Intent resultData) {
18255
18256        synchronized (this) {
18257            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18258            if (r != null) {
18259                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18260            }
18261            return false;
18262        }
18263    }
18264
18265    public int getLaunchedFromUid(IBinder activityToken) {
18266        ActivityRecord srec;
18267        synchronized (this) {
18268            srec = ActivityRecord.forTokenLocked(activityToken);
18269        }
18270        if (srec == null) {
18271            return -1;
18272        }
18273        return srec.launchedFromUid;
18274    }
18275
18276    public String getLaunchedFromPackage(IBinder activityToken) {
18277        ActivityRecord srec;
18278        synchronized (this) {
18279            srec = ActivityRecord.forTokenLocked(activityToken);
18280        }
18281        if (srec == null) {
18282            return null;
18283        }
18284        return srec.launchedFromPackage;
18285    }
18286
18287    // =========================================================
18288    // LIFETIME MANAGEMENT
18289    // =========================================================
18290
18291    // Returns which broadcast queue the app is the current [or imminent] receiver
18292    // on, or 'null' if the app is not an active broadcast recipient.
18293    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18294        BroadcastRecord r = app.curReceiver;
18295        if (r != null) {
18296            return r.queue;
18297        }
18298
18299        // It's not the current receiver, but it might be starting up to become one
18300        synchronized (this) {
18301            for (BroadcastQueue queue : mBroadcastQueues) {
18302                r = queue.mPendingBroadcast;
18303                if (r != null && r.curApp == app) {
18304                    // found it; report which queue it's in
18305                    return queue;
18306                }
18307            }
18308        }
18309
18310        return null;
18311    }
18312
18313    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18314            int targetUid, ComponentName targetComponent, String targetProcess) {
18315        if (!mTrackingAssociations) {
18316            return null;
18317        }
18318        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18319                = mAssociations.get(targetUid);
18320        if (components == null) {
18321            components = new ArrayMap<>();
18322            mAssociations.put(targetUid, components);
18323        }
18324        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18325        if (sourceUids == null) {
18326            sourceUids = new SparseArray<>();
18327            components.put(targetComponent, sourceUids);
18328        }
18329        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18330        if (sourceProcesses == null) {
18331            sourceProcesses = new ArrayMap<>();
18332            sourceUids.put(sourceUid, sourceProcesses);
18333        }
18334        Association ass = sourceProcesses.get(sourceProcess);
18335        if (ass == null) {
18336            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18337                    targetProcess);
18338            sourceProcesses.put(sourceProcess, ass);
18339        }
18340        ass.mCount++;
18341        ass.mNesting++;
18342        if (ass.mNesting == 1) {
18343            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18344            ass.mLastState = sourceState;
18345        }
18346        return ass;
18347    }
18348
18349    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18350            ComponentName targetComponent) {
18351        if (!mTrackingAssociations) {
18352            return;
18353        }
18354        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18355                = mAssociations.get(targetUid);
18356        if (components == null) {
18357            return;
18358        }
18359        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18360        if (sourceUids == null) {
18361            return;
18362        }
18363        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18364        if (sourceProcesses == null) {
18365            return;
18366        }
18367        Association ass = sourceProcesses.get(sourceProcess);
18368        if (ass == null || ass.mNesting <= 0) {
18369            return;
18370        }
18371        ass.mNesting--;
18372        if (ass.mNesting == 0) {
18373            long uptime = SystemClock.uptimeMillis();
18374            ass.mTime += uptime - ass.mStartTime;
18375            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18376                    += uptime - ass.mLastStateUptime;
18377            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18378        }
18379    }
18380
18381    private void noteUidProcessState(final int uid, final int state) {
18382        mBatteryStatsService.noteUidProcessState(uid, state);
18383        if (mTrackingAssociations) {
18384            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18385                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18386                        = mAssociations.valueAt(i1);
18387                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18388                    SparseArray<ArrayMap<String, Association>> sourceUids
18389                            = targetComponents.valueAt(i2);
18390                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18391                    if (sourceProcesses != null) {
18392                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18393                            Association ass = sourceProcesses.valueAt(i4);
18394                            if (ass.mNesting >= 1) {
18395                                // currently associated
18396                                long uptime = SystemClock.uptimeMillis();
18397                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18398                                        += uptime - ass.mLastStateUptime;
18399                                ass.mLastState = state;
18400                                ass.mLastStateUptime = uptime;
18401                            }
18402                        }
18403                    }
18404                }
18405            }
18406        }
18407    }
18408
18409    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18410            boolean doingAll, long now) {
18411        if (mAdjSeq == app.adjSeq) {
18412            // This adjustment has already been computed.
18413            return app.curRawAdj;
18414        }
18415
18416        if (app.thread == null) {
18417            app.adjSeq = mAdjSeq;
18418            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18419            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18420            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18421        }
18422
18423        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18424        app.adjSource = null;
18425        app.adjTarget = null;
18426        app.empty = false;
18427        app.cached = false;
18428
18429        final int activitiesSize = app.activities.size();
18430
18431        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18432            // The max adjustment doesn't allow this app to be anything
18433            // below foreground, so it is not worth doing work for it.
18434            app.adjType = "fixed";
18435            app.adjSeq = mAdjSeq;
18436            app.curRawAdj = app.maxAdj;
18437            app.foregroundActivities = false;
18438            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18439            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18440            // System processes can do UI, and when they do we want to have
18441            // them trim their memory after the user leaves the UI.  To
18442            // facilitate this, here we need to determine whether or not it
18443            // is currently showing UI.
18444            app.systemNoUi = true;
18445            if (app == TOP_APP) {
18446                app.systemNoUi = false;
18447            } else if (activitiesSize > 0) {
18448                for (int j = 0; j < activitiesSize; j++) {
18449                    final ActivityRecord r = app.activities.get(j);
18450                    if (r.visible) {
18451                        app.systemNoUi = false;
18452                    }
18453                }
18454            }
18455            if (!app.systemNoUi) {
18456                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18457            }
18458            return (app.curAdj=app.maxAdj);
18459        }
18460
18461        app.systemNoUi = false;
18462
18463        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18464
18465        // Determine the importance of the process, starting with most
18466        // important to least, and assign an appropriate OOM adjustment.
18467        int adj;
18468        int schedGroup;
18469        int procState;
18470        boolean foregroundActivities = false;
18471        BroadcastQueue queue;
18472        if (app == TOP_APP) {
18473            // The last app on the list is the foreground app.
18474            adj = ProcessList.FOREGROUND_APP_ADJ;
18475            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18476            app.adjType = "top-activity";
18477            foregroundActivities = true;
18478            procState = PROCESS_STATE_CUR_TOP;
18479        } else if (app.instrumentationClass != null) {
18480            // Don't want to kill running instrumentation.
18481            adj = ProcessList.FOREGROUND_APP_ADJ;
18482            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18483            app.adjType = "instrumentation";
18484            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18485        } else if ((queue = isReceivingBroadcast(app)) != null) {
18486            // An app that is currently receiving a broadcast also
18487            // counts as being in the foreground for OOM killer purposes.
18488            // It's placed in a sched group based on the nature of the
18489            // broadcast as reflected by which queue it's active in.
18490            adj = ProcessList.FOREGROUND_APP_ADJ;
18491            schedGroup = (queue == mFgBroadcastQueue)
18492                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18493            app.adjType = "broadcast";
18494            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18495        } else if (app.executingServices.size() > 0) {
18496            // An app that is currently executing a service callback also
18497            // counts as being in the foreground.
18498            adj = ProcessList.FOREGROUND_APP_ADJ;
18499            schedGroup = app.execServicesFg ?
18500                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18501            app.adjType = "exec-service";
18502            procState = ActivityManager.PROCESS_STATE_SERVICE;
18503            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18504        } else {
18505            // As far as we know the process is empty.  We may change our mind later.
18506            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18507            // At this point we don't actually know the adjustment.  Use the cached adj
18508            // value that the caller wants us to.
18509            adj = cachedAdj;
18510            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18511            app.cached = true;
18512            app.empty = true;
18513            app.adjType = "cch-empty";
18514        }
18515
18516        // Examine all activities if not already foreground.
18517        if (!foregroundActivities && activitiesSize > 0) {
18518            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18519            for (int j = 0; j < activitiesSize; j++) {
18520                final ActivityRecord r = app.activities.get(j);
18521                if (r.app != app) {
18522                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18523                            + " instead of expected " + app);
18524                    if (r.app == null || (r.app.uid == app.uid)) {
18525                        // Only fix things up when they look sane
18526                        r.app = app;
18527                    } else {
18528                        continue;
18529                    }
18530                }
18531                if (r.visible) {
18532                    // App has a visible activity; only upgrade adjustment.
18533                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18534                        adj = ProcessList.VISIBLE_APP_ADJ;
18535                        app.adjType = "visible";
18536                    }
18537                    if (procState > PROCESS_STATE_CUR_TOP) {
18538                        procState = PROCESS_STATE_CUR_TOP;
18539                    }
18540                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18541                    app.cached = false;
18542                    app.empty = false;
18543                    foregroundActivities = true;
18544                    if (r.task != null && minLayer > 0) {
18545                        final int layer = r.task.mLayerRank;
18546                        if (layer >= 0 && minLayer > layer) {
18547                            minLayer = layer;
18548                        }
18549                    }
18550                    break;
18551                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18552                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18553                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18554                        app.adjType = "pausing";
18555                    }
18556                    if (procState > PROCESS_STATE_CUR_TOP) {
18557                        procState = PROCESS_STATE_CUR_TOP;
18558                    }
18559                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18560                    app.cached = false;
18561                    app.empty = false;
18562                    foregroundActivities = true;
18563                } else if (r.state == ActivityState.STOPPING) {
18564                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18565                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18566                        app.adjType = "stopping";
18567                    }
18568                    // For the process state, we will at this point consider the
18569                    // process to be cached.  It will be cached either as an activity
18570                    // or empty depending on whether the activity is finishing.  We do
18571                    // this so that we can treat the process as cached for purposes of
18572                    // memory trimming (determing current memory level, trim command to
18573                    // send to process) since there can be an arbitrary number of stopping
18574                    // processes and they should soon all go into the cached state.
18575                    if (!r.finishing) {
18576                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18577                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18578                        }
18579                    }
18580                    app.cached = false;
18581                    app.empty = false;
18582                    foregroundActivities = true;
18583                } else {
18584                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18585                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18586                        app.adjType = "cch-act";
18587                    }
18588                }
18589            }
18590            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18591                adj += minLayer;
18592            }
18593        }
18594
18595        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18596                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18597            if (app.foregroundServices) {
18598                // The user is aware of this app, so make it visible.
18599                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18600                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18601                app.cached = false;
18602                app.adjType = "fg-service";
18603                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18604            } else if (app.forcingToForeground != null) {
18605                // The user is aware of this app, so make it visible.
18606                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18607                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18608                app.cached = false;
18609                app.adjType = "force-fg";
18610                app.adjSource = app.forcingToForeground;
18611                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18612            }
18613        }
18614
18615        if (app == mHeavyWeightProcess) {
18616            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18617                // We don't want to kill the current heavy-weight process.
18618                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18619                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18620                app.cached = false;
18621                app.adjType = "heavy";
18622            }
18623            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18624                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18625            }
18626        }
18627
18628        if (app == mHomeProcess) {
18629            if (adj > ProcessList.HOME_APP_ADJ) {
18630                // This process is hosting what we currently consider to be the
18631                // home app, so we don't want to let it go into the background.
18632                adj = ProcessList.HOME_APP_ADJ;
18633                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18634                app.cached = false;
18635                app.adjType = "home";
18636            }
18637            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18638                procState = ActivityManager.PROCESS_STATE_HOME;
18639            }
18640        }
18641
18642        if (app == mPreviousProcess && app.activities.size() > 0) {
18643            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18644                // This was the previous process that showed UI to the user.
18645                // We want to try to keep it around more aggressively, to give
18646                // a good experience around switching between two apps.
18647                adj = ProcessList.PREVIOUS_APP_ADJ;
18648                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18649                app.cached = false;
18650                app.adjType = "previous";
18651            }
18652            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18653                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18654            }
18655        }
18656
18657        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18658                + " reason=" + app.adjType);
18659
18660        // By default, we use the computed adjustment.  It may be changed if
18661        // there are applications dependent on our services or providers, but
18662        // this gives us a baseline and makes sure we don't get into an
18663        // infinite recursion.
18664        app.adjSeq = mAdjSeq;
18665        app.curRawAdj = adj;
18666        app.hasStartedServices = false;
18667
18668        if (mBackupTarget != null && app == mBackupTarget.app) {
18669            // If possible we want to avoid killing apps while they're being backed up
18670            if (adj > ProcessList.BACKUP_APP_ADJ) {
18671                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18672                adj = ProcessList.BACKUP_APP_ADJ;
18673                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18674                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18675                }
18676                app.adjType = "backup";
18677                app.cached = false;
18678            }
18679            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18680                procState = ActivityManager.PROCESS_STATE_BACKUP;
18681            }
18682        }
18683
18684        boolean mayBeTop = false;
18685
18686        for (int is = app.services.size()-1;
18687                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18688                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18689                        || procState > ActivityManager.PROCESS_STATE_TOP);
18690                is--) {
18691            ServiceRecord s = app.services.valueAt(is);
18692            if (s.startRequested) {
18693                app.hasStartedServices = true;
18694                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18695                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18696                }
18697                if (app.hasShownUi && app != mHomeProcess) {
18698                    // If this process has shown some UI, let it immediately
18699                    // go to the LRU list because it may be pretty heavy with
18700                    // UI stuff.  We'll tag it with a label just to help
18701                    // debug and understand what is going on.
18702                    if (adj > ProcessList.SERVICE_ADJ) {
18703                        app.adjType = "cch-started-ui-services";
18704                    }
18705                } else {
18706                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18707                        // This service has seen some activity within
18708                        // recent memory, so we will keep its process ahead
18709                        // of the background processes.
18710                        if (adj > ProcessList.SERVICE_ADJ) {
18711                            adj = ProcessList.SERVICE_ADJ;
18712                            app.adjType = "started-services";
18713                            app.cached = false;
18714                        }
18715                    }
18716                    // If we have let the service slide into the background
18717                    // state, still have some text describing what it is doing
18718                    // even though the service no longer has an impact.
18719                    if (adj > ProcessList.SERVICE_ADJ) {
18720                        app.adjType = "cch-started-services";
18721                    }
18722                }
18723            }
18724            for (int conni = s.connections.size()-1;
18725                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18726                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18727                            || procState > ActivityManager.PROCESS_STATE_TOP);
18728                    conni--) {
18729                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18730                for (int i = 0;
18731                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18732                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18733                                || procState > ActivityManager.PROCESS_STATE_TOP);
18734                        i++) {
18735                    // XXX should compute this based on the max of
18736                    // all connected clients.
18737                    ConnectionRecord cr = clist.get(i);
18738                    if (cr.binding.client == app) {
18739                        // Binding to ourself is not interesting.
18740                        continue;
18741                    }
18742                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18743                        ProcessRecord client = cr.binding.client;
18744                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18745                                TOP_APP, doingAll, now);
18746                        int clientProcState = client.curProcState;
18747                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18748                            // If the other app is cached for any reason, for purposes here
18749                            // we are going to consider it empty.  The specific cached state
18750                            // doesn't propagate except under certain conditions.
18751                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18752                        }
18753                        String adjType = null;
18754                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18755                            // Not doing bind OOM management, so treat
18756                            // this guy more like a started service.
18757                            if (app.hasShownUi && app != mHomeProcess) {
18758                                // If this process has shown some UI, let it immediately
18759                                // go to the LRU list because it may be pretty heavy with
18760                                // UI stuff.  We'll tag it with a label just to help
18761                                // debug and understand what is going on.
18762                                if (adj > clientAdj) {
18763                                    adjType = "cch-bound-ui-services";
18764                                }
18765                                app.cached = false;
18766                                clientAdj = adj;
18767                                clientProcState = procState;
18768                            } else {
18769                                if (now >= (s.lastActivity
18770                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18771                                    // This service has not seen activity within
18772                                    // recent memory, so allow it to drop to the
18773                                    // LRU list if there is no other reason to keep
18774                                    // it around.  We'll also tag it with a label just
18775                                    // to help debug and undertand what is going on.
18776                                    if (adj > clientAdj) {
18777                                        adjType = "cch-bound-services";
18778                                    }
18779                                    clientAdj = adj;
18780                                }
18781                            }
18782                        }
18783                        if (adj > clientAdj) {
18784                            // If this process has recently shown UI, and
18785                            // the process that is binding to it is less
18786                            // important than being visible, then we don't
18787                            // care about the binding as much as we care
18788                            // about letting this process get into the LRU
18789                            // list to be killed and restarted if needed for
18790                            // memory.
18791                            if (app.hasShownUi && app != mHomeProcess
18792                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18793                                adjType = "cch-bound-ui-services";
18794                            } else {
18795                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18796                                        |Context.BIND_IMPORTANT)) != 0) {
18797                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18798                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18799                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18800                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18801                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18802                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18803                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18804                                    adj = clientAdj;
18805                                } else {
18806                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18807                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18808                                    }
18809                                }
18810                                if (!client.cached) {
18811                                    app.cached = false;
18812                                }
18813                                adjType = "service";
18814                            }
18815                        }
18816                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18817                            // This will treat important bound services identically to
18818                            // the top app, which may behave differently than generic
18819                            // foreground work.
18820                            if (client.curSchedGroup > schedGroup) {
18821                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18822                                    schedGroup = client.curSchedGroup;
18823                                } else {
18824                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18825                                }
18826                            }
18827                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18828                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18829                                    // Special handling of clients who are in the top state.
18830                                    // We *may* want to consider this process to be in the
18831                                    // top state as well, but only if there is not another
18832                                    // reason for it to be running.  Being on the top is a
18833                                    // special state, meaning you are specifically running
18834                                    // for the current top app.  If the process is already
18835                                    // running in the background for some other reason, it
18836                                    // is more important to continue considering it to be
18837                                    // in the background state.
18838                                    mayBeTop = true;
18839                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18840                                } else {
18841                                    // Special handling for above-top states (persistent
18842                                    // processes).  These should not bring the current process
18843                                    // into the top state, since they are not on top.  Instead
18844                                    // give them the best state after that.
18845                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18846                                        clientProcState =
18847                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18848                                    } else if (mWakefulness
18849                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18850                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18851                                                    != 0) {
18852                                        clientProcState =
18853                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18854                                    } else {
18855                                        clientProcState =
18856                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18857                                    }
18858                                }
18859                            }
18860                        } else {
18861                            if (clientProcState <
18862                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18863                                clientProcState =
18864                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18865                            }
18866                        }
18867                        if (procState > clientProcState) {
18868                            procState = clientProcState;
18869                        }
18870                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18871                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18872                            app.pendingUiClean = true;
18873                        }
18874                        if (adjType != null) {
18875                            app.adjType = adjType;
18876                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18877                                    .REASON_SERVICE_IN_USE;
18878                            app.adjSource = cr.binding.client;
18879                            app.adjSourceProcState = clientProcState;
18880                            app.adjTarget = s.name;
18881                        }
18882                    }
18883                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18884                        app.treatLikeActivity = true;
18885                    }
18886                    final ActivityRecord a = cr.activity;
18887                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18888                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18889                            (a.visible || a.state == ActivityState.RESUMED ||
18890                             a.state == ActivityState.PAUSING)) {
18891                            adj = ProcessList.FOREGROUND_APP_ADJ;
18892                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18893                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18894                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18895                                } else {
18896                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18897                                }
18898                            }
18899                            app.cached = false;
18900                            app.adjType = "service";
18901                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18902                                    .REASON_SERVICE_IN_USE;
18903                            app.adjSource = a;
18904                            app.adjSourceProcState = procState;
18905                            app.adjTarget = s.name;
18906                        }
18907                    }
18908                }
18909            }
18910        }
18911
18912        for (int provi = app.pubProviders.size()-1;
18913                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18914                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18915                        || procState > ActivityManager.PROCESS_STATE_TOP);
18916                provi--) {
18917            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18918            for (int i = cpr.connections.size()-1;
18919                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18920                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18921                            || procState > ActivityManager.PROCESS_STATE_TOP);
18922                    i--) {
18923                ContentProviderConnection conn = cpr.connections.get(i);
18924                ProcessRecord client = conn.client;
18925                if (client == app) {
18926                    // Being our own client is not interesting.
18927                    continue;
18928                }
18929                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18930                int clientProcState = client.curProcState;
18931                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18932                    // If the other app is cached for any reason, for purposes here
18933                    // we are going to consider it empty.
18934                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18935                }
18936                if (adj > clientAdj) {
18937                    if (app.hasShownUi && app != mHomeProcess
18938                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18939                        app.adjType = "cch-ui-provider";
18940                    } else {
18941                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18942                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18943                        app.adjType = "provider";
18944                    }
18945                    app.cached &= client.cached;
18946                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18947                            .REASON_PROVIDER_IN_USE;
18948                    app.adjSource = client;
18949                    app.adjSourceProcState = clientProcState;
18950                    app.adjTarget = cpr.name;
18951                }
18952                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18953                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18954                        // Special handling of clients who are in the top state.
18955                        // We *may* want to consider this process to be in the
18956                        // top state as well, but only if there is not another
18957                        // reason for it to be running.  Being on the top is a
18958                        // special state, meaning you are specifically running
18959                        // for the current top app.  If the process is already
18960                        // running in the background for some other reason, it
18961                        // is more important to continue considering it to be
18962                        // in the background state.
18963                        mayBeTop = true;
18964                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18965                    } else {
18966                        // Special handling for above-top states (persistent
18967                        // processes).  These should not bring the current process
18968                        // into the top state, since they are not on top.  Instead
18969                        // give them the best state after that.
18970                        clientProcState =
18971                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18972                    }
18973                }
18974                if (procState > clientProcState) {
18975                    procState = clientProcState;
18976                }
18977                if (client.curSchedGroup > schedGroup) {
18978                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18979                }
18980            }
18981            // If the provider has external (non-framework) process
18982            // dependencies, ensure that its adjustment is at least
18983            // FOREGROUND_APP_ADJ.
18984            if (cpr.hasExternalProcessHandles()) {
18985                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18986                    adj = ProcessList.FOREGROUND_APP_ADJ;
18987                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18988                    app.cached = false;
18989                    app.adjType = "provider";
18990                    app.adjTarget = cpr.name;
18991                }
18992                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18993                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18994                }
18995            }
18996        }
18997
18998        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18999            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19000                adj = ProcessList.PREVIOUS_APP_ADJ;
19001                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19002                app.cached = false;
19003                app.adjType = "provider";
19004            }
19005            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19006                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19007            }
19008        }
19009
19010        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19011            // A client of one of our services or providers is in the top state.  We
19012            // *may* want to be in the top state, but not if we are already running in
19013            // the background for some other reason.  For the decision here, we are going
19014            // to pick out a few specific states that we want to remain in when a client
19015            // is top (states that tend to be longer-term) and otherwise allow it to go
19016            // to the top state.
19017            switch (procState) {
19018                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19019                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19020                case ActivityManager.PROCESS_STATE_SERVICE:
19021                    // These all are longer-term states, so pull them up to the top
19022                    // of the background states, but not all the way to the top state.
19023                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19024                    break;
19025                default:
19026                    // Otherwise, top is a better choice, so take it.
19027                    procState = ActivityManager.PROCESS_STATE_TOP;
19028                    break;
19029            }
19030        }
19031
19032        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19033            if (app.hasClientActivities) {
19034                // This is a cached process, but with client activities.  Mark it so.
19035                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19036                app.adjType = "cch-client-act";
19037            } else if (app.treatLikeActivity) {
19038                // This is a cached process, but somebody wants us to treat it like it has
19039                // an activity, okay!
19040                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19041                app.adjType = "cch-as-act";
19042            }
19043        }
19044
19045        if (adj == ProcessList.SERVICE_ADJ) {
19046            if (doingAll) {
19047                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19048                mNewNumServiceProcs++;
19049                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19050                if (!app.serviceb) {
19051                    // This service isn't far enough down on the LRU list to
19052                    // normally be a B service, but if we are low on RAM and it
19053                    // is large we want to force it down since we would prefer to
19054                    // keep launcher over it.
19055                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19056                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19057                        app.serviceHighRam = true;
19058                        app.serviceb = true;
19059                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19060                    } else {
19061                        mNewNumAServiceProcs++;
19062                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19063                    }
19064                } else {
19065                    app.serviceHighRam = false;
19066                }
19067            }
19068            if (app.serviceb) {
19069                adj = ProcessList.SERVICE_B_ADJ;
19070            }
19071        }
19072
19073        app.curRawAdj = adj;
19074
19075        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19076        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19077        if (adj > app.maxAdj) {
19078            adj = app.maxAdj;
19079            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19080                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19081            }
19082        }
19083
19084        // Do final modification to adj.  Everything we do between here and applying
19085        // the final setAdj must be done in this function, because we will also use
19086        // it when computing the final cached adj later.  Note that we don't need to
19087        // worry about this for max adj above, since max adj will always be used to
19088        // keep it out of the cached vaues.
19089        app.curAdj = app.modifyRawOomAdj(adj);
19090        app.curSchedGroup = schedGroup;
19091        app.curProcState = procState;
19092        app.foregroundActivities = foregroundActivities;
19093
19094        return app.curRawAdj;
19095    }
19096
19097    /**
19098     * Record new PSS sample for a process.
19099     */
19100    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19101            long now) {
19102        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19103                swapPss * 1024);
19104        proc.lastPssTime = now;
19105        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19106        if (DEBUG_PSS) Slog.d(TAG_PSS,
19107                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19108                + " state=" + ProcessList.makeProcStateString(procState));
19109        if (proc.initialIdlePss == 0) {
19110            proc.initialIdlePss = pss;
19111        }
19112        proc.lastPss = pss;
19113        proc.lastSwapPss = swapPss;
19114        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19115            proc.lastCachedPss = pss;
19116            proc.lastCachedSwapPss = swapPss;
19117        }
19118
19119        final SparseArray<Pair<Long, String>> watchUids
19120                = mMemWatchProcesses.getMap().get(proc.processName);
19121        Long check = null;
19122        if (watchUids != null) {
19123            Pair<Long, String> val = watchUids.get(proc.uid);
19124            if (val == null) {
19125                val = watchUids.get(0);
19126            }
19127            if (val != null) {
19128                check = val.first;
19129            }
19130        }
19131        if (check != null) {
19132            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19133                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19134                if (!isDebuggable) {
19135                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19136                        isDebuggable = true;
19137                    }
19138                }
19139                if (isDebuggable) {
19140                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19141                    final ProcessRecord myProc = proc;
19142                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19143                    mMemWatchDumpProcName = proc.processName;
19144                    mMemWatchDumpFile = heapdumpFile.toString();
19145                    mMemWatchDumpPid = proc.pid;
19146                    mMemWatchDumpUid = proc.uid;
19147                    BackgroundThread.getHandler().post(new Runnable() {
19148                        @Override
19149                        public void run() {
19150                            revokeUriPermission(ActivityThread.currentActivityThread()
19151                                            .getApplicationThread(),
19152                                    DumpHeapActivity.JAVA_URI,
19153                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19154                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19155                                    UserHandle.myUserId());
19156                            ParcelFileDescriptor fd = null;
19157                            try {
19158                                heapdumpFile.delete();
19159                                fd = ParcelFileDescriptor.open(heapdumpFile,
19160                                        ParcelFileDescriptor.MODE_CREATE |
19161                                                ParcelFileDescriptor.MODE_TRUNCATE |
19162                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19163                                                ParcelFileDescriptor.MODE_APPEND);
19164                                IApplicationThread thread = myProc.thread;
19165                                if (thread != null) {
19166                                    try {
19167                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19168                                                "Requesting dump heap from "
19169                                                + myProc + " to " + heapdumpFile);
19170                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19171                                    } catch (RemoteException e) {
19172                                    }
19173                                }
19174                            } catch (FileNotFoundException e) {
19175                                e.printStackTrace();
19176                            } finally {
19177                                if (fd != null) {
19178                                    try {
19179                                        fd.close();
19180                                    } catch (IOException e) {
19181                                    }
19182                                }
19183                            }
19184                        }
19185                    });
19186                } else {
19187                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19188                            + ", but debugging not enabled");
19189                }
19190            }
19191        }
19192    }
19193
19194    /**
19195     * Schedule PSS collection of a process.
19196     */
19197    void requestPssLocked(ProcessRecord proc, int procState) {
19198        if (mPendingPssProcesses.contains(proc)) {
19199            return;
19200        }
19201        if (mPendingPssProcesses.size() == 0) {
19202            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19203        }
19204        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19205        proc.pssProcState = procState;
19206        mPendingPssProcesses.add(proc);
19207    }
19208
19209    /**
19210     * Schedule PSS collection of all processes.
19211     */
19212    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19213        if (!always) {
19214            if (now < (mLastFullPssTime +
19215                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19216                return;
19217            }
19218        }
19219        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19220        mLastFullPssTime = now;
19221        mFullPssPending = true;
19222        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19223        mPendingPssProcesses.clear();
19224        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19225            ProcessRecord app = mLruProcesses.get(i);
19226            if (app.thread == null
19227                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19228                continue;
19229            }
19230            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19231                app.pssProcState = app.setProcState;
19232                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19233                        mTestPssMode, isSleeping(), now);
19234                mPendingPssProcesses.add(app);
19235            }
19236        }
19237        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19238    }
19239
19240    public void setTestPssMode(boolean enabled) {
19241        synchronized (this) {
19242            mTestPssMode = enabled;
19243            if (enabled) {
19244                // Whenever we enable the mode, we want to take a snapshot all of current
19245                // process mem use.
19246                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19247            }
19248        }
19249    }
19250
19251    /**
19252     * Ask a given process to GC right now.
19253     */
19254    final void performAppGcLocked(ProcessRecord app) {
19255        try {
19256            app.lastRequestedGc = SystemClock.uptimeMillis();
19257            if (app.thread != null) {
19258                if (app.reportLowMemory) {
19259                    app.reportLowMemory = false;
19260                    app.thread.scheduleLowMemory();
19261                } else {
19262                    app.thread.processInBackground();
19263                }
19264            }
19265        } catch (Exception e) {
19266            // whatever.
19267        }
19268    }
19269
19270    /**
19271     * Returns true if things are idle enough to perform GCs.
19272     */
19273    private final boolean canGcNowLocked() {
19274        boolean processingBroadcasts = false;
19275        for (BroadcastQueue q : mBroadcastQueues) {
19276            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19277                processingBroadcasts = true;
19278            }
19279        }
19280        return !processingBroadcasts
19281                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19282    }
19283
19284    /**
19285     * Perform GCs on all processes that are waiting for it, but only
19286     * if things are idle.
19287     */
19288    final void performAppGcsLocked() {
19289        final int N = mProcessesToGc.size();
19290        if (N <= 0) {
19291            return;
19292        }
19293        if (canGcNowLocked()) {
19294            while (mProcessesToGc.size() > 0) {
19295                ProcessRecord proc = mProcessesToGc.remove(0);
19296                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19297                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19298                            <= SystemClock.uptimeMillis()) {
19299                        // To avoid spamming the system, we will GC processes one
19300                        // at a time, waiting a few seconds between each.
19301                        performAppGcLocked(proc);
19302                        scheduleAppGcsLocked();
19303                        return;
19304                    } else {
19305                        // It hasn't been long enough since we last GCed this
19306                        // process...  put it in the list to wait for its time.
19307                        addProcessToGcListLocked(proc);
19308                        break;
19309                    }
19310                }
19311            }
19312
19313            scheduleAppGcsLocked();
19314        }
19315    }
19316
19317    /**
19318     * If all looks good, perform GCs on all processes waiting for them.
19319     */
19320    final void performAppGcsIfAppropriateLocked() {
19321        if (canGcNowLocked()) {
19322            performAppGcsLocked();
19323            return;
19324        }
19325        // Still not idle, wait some more.
19326        scheduleAppGcsLocked();
19327    }
19328
19329    /**
19330     * Schedule the execution of all pending app GCs.
19331     */
19332    final void scheduleAppGcsLocked() {
19333        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19334
19335        if (mProcessesToGc.size() > 0) {
19336            // Schedule a GC for the time to the next process.
19337            ProcessRecord proc = mProcessesToGc.get(0);
19338            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19339
19340            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19341            long now = SystemClock.uptimeMillis();
19342            if (when < (now+GC_TIMEOUT)) {
19343                when = now + GC_TIMEOUT;
19344            }
19345            mHandler.sendMessageAtTime(msg, when);
19346        }
19347    }
19348
19349    /**
19350     * Add a process to the array of processes waiting to be GCed.  Keeps the
19351     * list in sorted order by the last GC time.  The process can't already be
19352     * on the list.
19353     */
19354    final void addProcessToGcListLocked(ProcessRecord proc) {
19355        boolean added = false;
19356        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19357            if (mProcessesToGc.get(i).lastRequestedGc <
19358                    proc.lastRequestedGc) {
19359                added = true;
19360                mProcessesToGc.add(i+1, proc);
19361                break;
19362            }
19363        }
19364        if (!added) {
19365            mProcessesToGc.add(0, proc);
19366        }
19367    }
19368
19369    /**
19370     * Set up to ask a process to GC itself.  This will either do it
19371     * immediately, or put it on the list of processes to gc the next
19372     * time things are idle.
19373     */
19374    final void scheduleAppGcLocked(ProcessRecord app) {
19375        long now = SystemClock.uptimeMillis();
19376        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19377            return;
19378        }
19379        if (!mProcessesToGc.contains(app)) {
19380            addProcessToGcListLocked(app);
19381            scheduleAppGcsLocked();
19382        }
19383    }
19384
19385    final void checkExcessivePowerUsageLocked(boolean doKills) {
19386        updateCpuStatsNow();
19387
19388        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19389        boolean doWakeKills = doKills;
19390        boolean doCpuKills = doKills;
19391        if (mLastPowerCheckRealtime == 0) {
19392            doWakeKills = false;
19393        }
19394        if (mLastPowerCheckUptime == 0) {
19395            doCpuKills = false;
19396        }
19397        if (stats.isScreenOn()) {
19398            doWakeKills = false;
19399        }
19400        final long curRealtime = SystemClock.elapsedRealtime();
19401        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19402        final long curUptime = SystemClock.uptimeMillis();
19403        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19404        mLastPowerCheckRealtime = curRealtime;
19405        mLastPowerCheckUptime = curUptime;
19406        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19407            doWakeKills = false;
19408        }
19409        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19410            doCpuKills = false;
19411        }
19412        int i = mLruProcesses.size();
19413        while (i > 0) {
19414            i--;
19415            ProcessRecord app = mLruProcesses.get(i);
19416            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19417                long wtime;
19418                synchronized (stats) {
19419                    wtime = stats.getProcessWakeTime(app.info.uid,
19420                            app.pid, curRealtime);
19421                }
19422                long wtimeUsed = wtime - app.lastWakeTime;
19423                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19424                if (DEBUG_POWER) {
19425                    StringBuilder sb = new StringBuilder(128);
19426                    sb.append("Wake for ");
19427                    app.toShortString(sb);
19428                    sb.append(": over ");
19429                    TimeUtils.formatDuration(realtimeSince, sb);
19430                    sb.append(" used ");
19431                    TimeUtils.formatDuration(wtimeUsed, sb);
19432                    sb.append(" (");
19433                    sb.append((wtimeUsed*100)/realtimeSince);
19434                    sb.append("%)");
19435                    Slog.i(TAG_POWER, sb.toString());
19436                    sb.setLength(0);
19437                    sb.append("CPU for ");
19438                    app.toShortString(sb);
19439                    sb.append(": over ");
19440                    TimeUtils.formatDuration(uptimeSince, sb);
19441                    sb.append(" used ");
19442                    TimeUtils.formatDuration(cputimeUsed, sb);
19443                    sb.append(" (");
19444                    sb.append((cputimeUsed*100)/uptimeSince);
19445                    sb.append("%)");
19446                    Slog.i(TAG_POWER, sb.toString());
19447                }
19448                // If a process has held a wake lock for more
19449                // than 50% of the time during this period,
19450                // that sounds bad.  Kill!
19451                if (doWakeKills && realtimeSince > 0
19452                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19453                    synchronized (stats) {
19454                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19455                                realtimeSince, wtimeUsed);
19456                    }
19457                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19458                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19459                } else if (doCpuKills && uptimeSince > 0
19460                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19461                    synchronized (stats) {
19462                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19463                                uptimeSince, cputimeUsed);
19464                    }
19465                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19466                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19467                } else {
19468                    app.lastWakeTime = wtime;
19469                    app.lastCpuTime = app.curCpuTime;
19470                }
19471            }
19472        }
19473    }
19474
19475    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19476            long nowElapsed) {
19477        boolean success = true;
19478
19479        if (app.curRawAdj != app.setRawAdj) {
19480            app.setRawAdj = app.curRawAdj;
19481        }
19482
19483        int changes = 0;
19484
19485        if (app.curAdj != app.setAdj) {
19486            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19487            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19488                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19489                    + app.adjType);
19490            app.setAdj = app.curAdj;
19491        }
19492
19493        if (app.setSchedGroup != app.curSchedGroup) {
19494            app.setSchedGroup = app.curSchedGroup;
19495            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19496                    "Setting sched group of " + app.processName
19497                    + " to " + app.curSchedGroup);
19498            if (app.waitingToKill != null && app.curReceiver == null
19499                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19500                app.kill(app.waitingToKill, true);
19501                success = false;
19502            } else {
19503                int processGroup;
19504                switch (app.curSchedGroup) {
19505                    case ProcessList.SCHED_GROUP_BACKGROUND:
19506                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19507                        break;
19508                    case ProcessList.SCHED_GROUP_TOP_APP:
19509                        processGroup = Process.THREAD_GROUP_TOP_APP;
19510                        break;
19511                    default:
19512                        processGroup = Process.THREAD_GROUP_DEFAULT;
19513                        break;
19514                }
19515                if (true) {
19516                    long oldId = Binder.clearCallingIdentity();
19517                    try {
19518                        Process.setProcessGroup(app.pid, processGroup);
19519                    } catch (Exception e) {
19520                        Slog.w(TAG, "Failed setting process group of " + app.pid
19521                                + " to " + app.curSchedGroup);
19522                        e.printStackTrace();
19523                    } finally {
19524                        Binder.restoreCallingIdentity(oldId);
19525                    }
19526                } else {
19527                    if (app.thread != null) {
19528                        try {
19529                            app.thread.setSchedulingGroup(processGroup);
19530                        } catch (RemoteException e) {
19531                        }
19532                    }
19533                }
19534            }
19535        }
19536        if (app.repForegroundActivities != app.foregroundActivities) {
19537            app.repForegroundActivities = app.foregroundActivities;
19538            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19539        }
19540        if (app.repProcState != app.curProcState) {
19541            app.repProcState = app.curProcState;
19542            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19543            if (app.thread != null) {
19544                try {
19545                    if (false) {
19546                        //RuntimeException h = new RuntimeException("here");
19547                        Slog.i(TAG, "Sending new process state " + app.repProcState
19548                                + " to " + app /*, h*/);
19549                    }
19550                    app.thread.setProcessState(app.repProcState);
19551                } catch (RemoteException e) {
19552                }
19553            }
19554        }
19555        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19556                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19557            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19558                // Experimental code to more aggressively collect pss while
19559                // running test...  the problem is that this tends to collect
19560                // the data right when a process is transitioning between process
19561                // states, which well tend to give noisy data.
19562                long start = SystemClock.uptimeMillis();
19563                long pss = Debug.getPss(app.pid, mTmpLong, null);
19564                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19565                mPendingPssProcesses.remove(app);
19566                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19567                        + " to " + app.curProcState + ": "
19568                        + (SystemClock.uptimeMillis()-start) + "ms");
19569            }
19570            app.lastStateTime = now;
19571            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19572                    mTestPssMode, isSleeping(), now);
19573            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19574                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19575                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19576                    + (app.nextPssTime-now) + ": " + app);
19577        } else {
19578            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19579                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19580                    mTestPssMode)))) {
19581                requestPssLocked(app, app.setProcState);
19582                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19583                        mTestPssMode, isSleeping(), now);
19584            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19585                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19586        }
19587        if (app.setProcState != app.curProcState) {
19588            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19589                    "Proc state change of " + app.processName
19590                            + " to " + app.curProcState);
19591            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19592            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19593            if (setImportant && !curImportant) {
19594                // This app is no longer something we consider important enough to allow to
19595                // use arbitrary amounts of battery power.  Note
19596                // its current wake lock time to later know to kill it if
19597                // it is not behaving well.
19598                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19599                synchronized (stats) {
19600                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19601                            app.pid, nowElapsed);
19602                }
19603                app.lastCpuTime = app.curCpuTime;
19604
19605            }
19606            // Inform UsageStats of important process state change
19607            // Must be called before updating setProcState
19608            maybeUpdateUsageStatsLocked(app, nowElapsed);
19609
19610            app.setProcState = app.curProcState;
19611            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19612                app.notCachedSinceIdle = false;
19613            }
19614            if (!doingAll) {
19615                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19616            } else {
19617                app.procStateChanged = true;
19618            }
19619        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19620                > USAGE_STATS_INTERACTION_INTERVAL) {
19621            // For apps that sit around for a long time in the interactive state, we need
19622            // to report this at least once a day so they don't go idle.
19623            maybeUpdateUsageStatsLocked(app, nowElapsed);
19624        }
19625
19626        if (changes != 0) {
19627            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19628                    "Changes in " + app + ": " + changes);
19629            int i = mPendingProcessChanges.size()-1;
19630            ProcessChangeItem item = null;
19631            while (i >= 0) {
19632                item = mPendingProcessChanges.get(i);
19633                if (item.pid == app.pid) {
19634                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19635                            "Re-using existing item: " + item);
19636                    break;
19637                }
19638                i--;
19639            }
19640            if (i < 0) {
19641                // No existing item in pending changes; need a new one.
19642                final int NA = mAvailProcessChanges.size();
19643                if (NA > 0) {
19644                    item = mAvailProcessChanges.remove(NA-1);
19645                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19646                            "Retrieving available item: " + item);
19647                } else {
19648                    item = new ProcessChangeItem();
19649                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19650                            "Allocating new item: " + item);
19651                }
19652                item.changes = 0;
19653                item.pid = app.pid;
19654                item.uid = app.info.uid;
19655                if (mPendingProcessChanges.size() == 0) {
19656                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19657                            "*** Enqueueing dispatch processes changed!");
19658                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19659                }
19660                mPendingProcessChanges.add(item);
19661            }
19662            item.changes |= changes;
19663            item.processState = app.repProcState;
19664            item.foregroundActivities = app.repForegroundActivities;
19665            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19666                    "Item " + Integer.toHexString(System.identityHashCode(item))
19667                    + " " + app.toShortString() + ": changes=" + item.changes
19668                    + " procState=" + item.processState
19669                    + " foreground=" + item.foregroundActivities
19670                    + " type=" + app.adjType + " source=" + app.adjSource
19671                    + " target=" + app.adjTarget);
19672        }
19673
19674        return success;
19675    }
19676
19677    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19678        final UidRecord.ChangeItem pendingChange;
19679        if (uidRec == null || uidRec.pendingChange == null) {
19680            if (mPendingUidChanges.size() == 0) {
19681                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19682                        "*** Enqueueing dispatch uid changed!");
19683                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19684            }
19685            final int NA = mAvailUidChanges.size();
19686            if (NA > 0) {
19687                pendingChange = mAvailUidChanges.remove(NA-1);
19688                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19689                        "Retrieving available item: " + pendingChange);
19690            } else {
19691                pendingChange = new UidRecord.ChangeItem();
19692                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19693                        "Allocating new item: " + pendingChange);
19694            }
19695            if (uidRec != null) {
19696                uidRec.pendingChange = pendingChange;
19697                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19698                    // If this uid is going away, and we haven't yet reported it is gone,
19699                    // then do so now.
19700                    change = UidRecord.CHANGE_GONE_IDLE;
19701                }
19702            } else if (uid < 0) {
19703                throw new IllegalArgumentException("No UidRecord or uid");
19704            }
19705            pendingChange.uidRecord = uidRec;
19706            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19707            mPendingUidChanges.add(pendingChange);
19708        } else {
19709            pendingChange = uidRec.pendingChange;
19710            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19711                change = UidRecord.CHANGE_GONE_IDLE;
19712            }
19713        }
19714        pendingChange.change = change;
19715        pendingChange.processState = uidRec != null
19716                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19717    }
19718
19719    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19720            String authority) {
19721        if (app == null) return;
19722        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19723            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19724            if (userState == null) return;
19725            final long now = SystemClock.elapsedRealtime();
19726            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19727            if (lastReported == null || lastReported < now - 60 * 1000L) {
19728                mUsageStatsService.reportContentProviderUsage(
19729                        authority, providerPkgName, app.userId);
19730                userState.mProviderLastReportedFg.put(authority, now);
19731            }
19732        }
19733    }
19734
19735    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19736        if (DEBUG_USAGE_STATS) {
19737            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19738                    + "] state changes: old = " + app.setProcState + ", new = "
19739                    + app.curProcState);
19740        }
19741        if (mUsageStatsService == null) {
19742            return;
19743        }
19744        boolean isInteraction;
19745        // To avoid some abuse patterns, we are going to be careful about what we consider
19746        // to be an app interaction.  Being the top activity doesn't count while the display
19747        // is sleeping, nor do short foreground services.
19748        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19749            isInteraction = true;
19750            app.fgInteractionTime = 0;
19751        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19752            if (app.fgInteractionTime == 0) {
19753                app.fgInteractionTime = nowElapsed;
19754                isInteraction = false;
19755            } else {
19756                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19757            }
19758        } else {
19759            isInteraction = app.curProcState
19760                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19761            app.fgInteractionTime = 0;
19762        }
19763        if (isInteraction && (!app.reportedInteraction
19764                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19765            app.interactionEventTime = nowElapsed;
19766            String[] packages = app.getPackageList();
19767            if (packages != null) {
19768                for (int i = 0; i < packages.length; i++) {
19769                    mUsageStatsService.reportEvent(packages[i], app.userId,
19770                            UsageEvents.Event.SYSTEM_INTERACTION);
19771                }
19772            }
19773        }
19774        app.reportedInteraction = isInteraction;
19775        if (!isInteraction) {
19776            app.interactionEventTime = 0;
19777        }
19778    }
19779
19780    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19781        if (proc.thread != null) {
19782            if (proc.baseProcessTracker != null) {
19783                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19784            }
19785        }
19786    }
19787
19788    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19789            ProcessRecord TOP_APP, boolean doingAll, long now) {
19790        if (app.thread == null) {
19791            return false;
19792        }
19793
19794        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19795
19796        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19797    }
19798
19799    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19800            boolean oomAdj) {
19801        if (isForeground != proc.foregroundServices) {
19802            proc.foregroundServices = isForeground;
19803            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19804                    proc.info.uid);
19805            if (isForeground) {
19806                if (curProcs == null) {
19807                    curProcs = new ArrayList<ProcessRecord>();
19808                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19809                }
19810                if (!curProcs.contains(proc)) {
19811                    curProcs.add(proc);
19812                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19813                            proc.info.packageName, proc.info.uid);
19814                }
19815            } else {
19816                if (curProcs != null) {
19817                    if (curProcs.remove(proc)) {
19818                        mBatteryStatsService.noteEvent(
19819                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19820                                proc.info.packageName, proc.info.uid);
19821                        if (curProcs.size() <= 0) {
19822                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19823                        }
19824                    }
19825                }
19826            }
19827            if (oomAdj) {
19828                updateOomAdjLocked();
19829            }
19830        }
19831    }
19832
19833    private final ActivityRecord resumedAppLocked() {
19834        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19835        String pkg;
19836        int uid;
19837        if (act != null) {
19838            pkg = act.packageName;
19839            uid = act.info.applicationInfo.uid;
19840        } else {
19841            pkg = null;
19842            uid = -1;
19843        }
19844        // Has the UID or resumed package name changed?
19845        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19846                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19847            if (mCurResumedPackage != null) {
19848                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19849                        mCurResumedPackage, mCurResumedUid);
19850            }
19851            mCurResumedPackage = pkg;
19852            mCurResumedUid = uid;
19853            if (mCurResumedPackage != null) {
19854                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19855                        mCurResumedPackage, mCurResumedUid);
19856            }
19857        }
19858        return act;
19859    }
19860
19861    final boolean updateOomAdjLocked(ProcessRecord app) {
19862        final ActivityRecord TOP_ACT = resumedAppLocked();
19863        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19864        final boolean wasCached = app.cached;
19865
19866        mAdjSeq++;
19867
19868        // This is the desired cached adjusment we want to tell it to use.
19869        // If our app is currently cached, we know it, and that is it.  Otherwise,
19870        // we don't know it yet, and it needs to now be cached we will then
19871        // need to do a complete oom adj.
19872        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19873                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19874        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19875                SystemClock.uptimeMillis());
19876        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19877            // Changed to/from cached state, so apps after it in the LRU
19878            // list may also be changed.
19879            updateOomAdjLocked();
19880        }
19881        return success;
19882    }
19883
19884    final void updateOomAdjLocked() {
19885        final ActivityRecord TOP_ACT = resumedAppLocked();
19886        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19887        final long now = SystemClock.uptimeMillis();
19888        final long nowElapsed = SystemClock.elapsedRealtime();
19889        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19890        final int N = mLruProcesses.size();
19891
19892        if (false) {
19893            RuntimeException e = new RuntimeException();
19894            e.fillInStackTrace();
19895            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19896        }
19897
19898        // Reset state in all uid records.
19899        for (int i=mActiveUids.size()-1; i>=0; i--) {
19900            final UidRecord uidRec = mActiveUids.valueAt(i);
19901            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19902                    "Starting update of " + uidRec);
19903            uidRec.reset();
19904        }
19905
19906        mStackSupervisor.rankTaskLayersIfNeeded();
19907
19908        mAdjSeq++;
19909        mNewNumServiceProcs = 0;
19910        mNewNumAServiceProcs = 0;
19911
19912        final int emptyProcessLimit;
19913        final int cachedProcessLimit;
19914        if (mProcessLimit <= 0) {
19915            emptyProcessLimit = cachedProcessLimit = 0;
19916        } else if (mProcessLimit == 1) {
19917            emptyProcessLimit = 1;
19918            cachedProcessLimit = 0;
19919        } else {
19920            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19921            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19922        }
19923
19924        // Let's determine how many processes we have running vs.
19925        // how many slots we have for background processes; we may want
19926        // to put multiple processes in a slot of there are enough of
19927        // them.
19928        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19929                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19930        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19931        if (numEmptyProcs > cachedProcessLimit) {
19932            // If there are more empty processes than our limit on cached
19933            // processes, then use the cached process limit for the factor.
19934            // This ensures that the really old empty processes get pushed
19935            // down to the bottom, so if we are running low on memory we will
19936            // have a better chance at keeping around more cached processes
19937            // instead of a gazillion empty processes.
19938            numEmptyProcs = cachedProcessLimit;
19939        }
19940        int emptyFactor = numEmptyProcs/numSlots;
19941        if (emptyFactor < 1) emptyFactor = 1;
19942        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19943        if (cachedFactor < 1) cachedFactor = 1;
19944        int stepCached = 0;
19945        int stepEmpty = 0;
19946        int numCached = 0;
19947        int numEmpty = 0;
19948        int numTrimming = 0;
19949
19950        mNumNonCachedProcs = 0;
19951        mNumCachedHiddenProcs = 0;
19952
19953        // First update the OOM adjustment for each of the
19954        // application processes based on their current state.
19955        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19956        int nextCachedAdj = curCachedAdj+1;
19957        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19958        int nextEmptyAdj = curEmptyAdj+2;
19959        for (int i=N-1; i>=0; i--) {
19960            ProcessRecord app = mLruProcesses.get(i);
19961            if (!app.killedByAm && app.thread != null) {
19962                app.procStateChanged = false;
19963                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19964
19965                // If we haven't yet assigned the final cached adj
19966                // to the process, do that now.
19967                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19968                    switch (app.curProcState) {
19969                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19970                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19971                            // This process is a cached process holding activities...
19972                            // assign it the next cached value for that type, and then
19973                            // step that cached level.
19974                            app.curRawAdj = curCachedAdj;
19975                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19976                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19977                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19978                                    + ")");
19979                            if (curCachedAdj != nextCachedAdj) {
19980                                stepCached++;
19981                                if (stepCached >= cachedFactor) {
19982                                    stepCached = 0;
19983                                    curCachedAdj = nextCachedAdj;
19984                                    nextCachedAdj += 2;
19985                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19986                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19987                                    }
19988                                }
19989                            }
19990                            break;
19991                        default:
19992                            // For everything else, assign next empty cached process
19993                            // level and bump that up.  Note that this means that
19994                            // long-running services that have dropped down to the
19995                            // cached level will be treated as empty (since their process
19996                            // state is still as a service), which is what we want.
19997                            app.curRawAdj = curEmptyAdj;
19998                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19999                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20000                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20001                                    + ")");
20002                            if (curEmptyAdj != nextEmptyAdj) {
20003                                stepEmpty++;
20004                                if (stepEmpty >= emptyFactor) {
20005                                    stepEmpty = 0;
20006                                    curEmptyAdj = nextEmptyAdj;
20007                                    nextEmptyAdj += 2;
20008                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20009                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20010                                    }
20011                                }
20012                            }
20013                            break;
20014                    }
20015                }
20016
20017                applyOomAdjLocked(app, true, now, nowElapsed);
20018
20019                // Count the number of process types.
20020                switch (app.curProcState) {
20021                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20022                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20023                        mNumCachedHiddenProcs++;
20024                        numCached++;
20025                        if (numCached > cachedProcessLimit) {
20026                            app.kill("cached #" + numCached, true);
20027                        }
20028                        break;
20029                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20030                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20031                                && app.lastActivityTime < oldTime) {
20032                            app.kill("empty for "
20033                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20034                                    / 1000) + "s", true);
20035                        } else {
20036                            numEmpty++;
20037                            if (numEmpty > emptyProcessLimit) {
20038                                app.kill("empty #" + numEmpty, true);
20039                            }
20040                        }
20041                        break;
20042                    default:
20043                        mNumNonCachedProcs++;
20044                        break;
20045                }
20046
20047                if (app.isolated && app.services.size() <= 0) {
20048                    // If this is an isolated process, and there are no
20049                    // services running in it, then the process is no longer
20050                    // needed.  We agressively kill these because we can by
20051                    // definition not re-use the same process again, and it is
20052                    // good to avoid having whatever code was running in them
20053                    // left sitting around after no longer needed.
20054                    app.kill("isolated not needed", true);
20055                } else {
20056                    // Keeping this process, update its uid.
20057                    final UidRecord uidRec = app.uidRecord;
20058                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20059                        uidRec.curProcState = app.curProcState;
20060                    }
20061                }
20062
20063                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20064                        && !app.killedByAm) {
20065                    numTrimming++;
20066                }
20067            }
20068        }
20069
20070        mNumServiceProcs = mNewNumServiceProcs;
20071
20072        // Now determine the memory trimming level of background processes.
20073        // Unfortunately we need to start at the back of the list to do this
20074        // properly.  We only do this if the number of background apps we
20075        // are managing to keep around is less than half the maximum we desire;
20076        // if we are keeping a good number around, we'll let them use whatever
20077        // memory they want.
20078        final int numCachedAndEmpty = numCached + numEmpty;
20079        int memFactor;
20080        if (numCached <= ProcessList.TRIM_CACHED_APPS
20081                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20082            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20083                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20084            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20085                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20086            } else {
20087                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20088            }
20089        } else {
20090            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20091        }
20092        // We always allow the memory level to go up (better).  We only allow it to go
20093        // down if we are in a state where that is allowed, *and* the total number of processes
20094        // has gone down since last time.
20095        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20096                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20097                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20098        if (memFactor > mLastMemoryLevel) {
20099            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20100                memFactor = mLastMemoryLevel;
20101                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20102            }
20103        }
20104        mLastMemoryLevel = memFactor;
20105        mLastNumProcesses = mLruProcesses.size();
20106        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20107        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20108        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20109            if (mLowRamStartTime == 0) {
20110                mLowRamStartTime = now;
20111            }
20112            int step = 0;
20113            int fgTrimLevel;
20114            switch (memFactor) {
20115                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20116                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20117                    break;
20118                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20119                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20120                    break;
20121                default:
20122                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20123                    break;
20124            }
20125            int factor = numTrimming/3;
20126            int minFactor = 2;
20127            if (mHomeProcess != null) minFactor++;
20128            if (mPreviousProcess != null) minFactor++;
20129            if (factor < minFactor) factor = minFactor;
20130            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20131            for (int i=N-1; i>=0; i--) {
20132                ProcessRecord app = mLruProcesses.get(i);
20133                if (allChanged || app.procStateChanged) {
20134                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20135                    app.procStateChanged = false;
20136                }
20137                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20138                        && !app.killedByAm) {
20139                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20140                        try {
20141                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20142                                    "Trimming memory of " + app.processName + " to " + curLevel);
20143                            app.thread.scheduleTrimMemory(curLevel);
20144                        } catch (RemoteException e) {
20145                        }
20146                        if (false) {
20147                            // For now we won't do this; our memory trimming seems
20148                            // to be good enough at this point that destroying
20149                            // activities causes more harm than good.
20150                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20151                                    && app != mHomeProcess && app != mPreviousProcess) {
20152                                // Need to do this on its own message because the stack may not
20153                                // be in a consistent state at this point.
20154                                // For these apps we will also finish their activities
20155                                // to help them free memory.
20156                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20157                            }
20158                        }
20159                    }
20160                    app.trimMemoryLevel = curLevel;
20161                    step++;
20162                    if (step >= factor) {
20163                        step = 0;
20164                        switch (curLevel) {
20165                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20166                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20167                                break;
20168                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20169                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20170                                break;
20171                        }
20172                    }
20173                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20174                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20175                            && app.thread != null) {
20176                        try {
20177                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20178                                    "Trimming memory of heavy-weight " + app.processName
20179                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20180                            app.thread.scheduleTrimMemory(
20181                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20182                        } catch (RemoteException e) {
20183                        }
20184                    }
20185                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20186                } else {
20187                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20188                            || app.systemNoUi) && app.pendingUiClean) {
20189                        // If this application is now in the background and it
20190                        // had done UI, then give it the special trim level to
20191                        // have it free UI resources.
20192                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20193                        if (app.trimMemoryLevel < level && app.thread != null) {
20194                            try {
20195                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20196                                        "Trimming memory of bg-ui " + app.processName
20197                                        + " to " + level);
20198                                app.thread.scheduleTrimMemory(level);
20199                            } catch (RemoteException e) {
20200                            }
20201                        }
20202                        app.pendingUiClean = false;
20203                    }
20204                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20205                        try {
20206                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20207                                    "Trimming memory of fg " + app.processName
20208                                    + " to " + fgTrimLevel);
20209                            app.thread.scheduleTrimMemory(fgTrimLevel);
20210                        } catch (RemoteException e) {
20211                        }
20212                    }
20213                    app.trimMemoryLevel = fgTrimLevel;
20214                }
20215            }
20216        } else {
20217            if (mLowRamStartTime != 0) {
20218                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20219                mLowRamStartTime = 0;
20220            }
20221            for (int i=N-1; i>=0; i--) {
20222                ProcessRecord app = mLruProcesses.get(i);
20223                if (allChanged || app.procStateChanged) {
20224                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20225                    app.procStateChanged = false;
20226                }
20227                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20228                        || app.systemNoUi) && app.pendingUiClean) {
20229                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20230                            && app.thread != null) {
20231                        try {
20232                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20233                                    "Trimming memory of ui hidden " + app.processName
20234                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20235                            app.thread.scheduleTrimMemory(
20236                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20237                        } catch (RemoteException e) {
20238                        }
20239                    }
20240                    app.pendingUiClean = false;
20241                }
20242                app.trimMemoryLevel = 0;
20243            }
20244        }
20245
20246        if (mAlwaysFinishActivities) {
20247            // Need to do this on its own message because the stack may not
20248            // be in a consistent state at this point.
20249            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20250        }
20251
20252        if (allChanged) {
20253            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20254        }
20255
20256        // Update from any uid changes.
20257        for (int i=mActiveUids.size()-1; i>=0; i--) {
20258            final UidRecord uidRec = mActiveUids.valueAt(i);
20259            int uidChange = UidRecord.CHANGE_PROCSTATE;
20260            if (uidRec.setProcState != uidRec.curProcState) {
20261                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20262                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20263                        + " to " + uidRec.curProcState);
20264                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20265                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20266                        uidRec.lastBackgroundTime = nowElapsed;
20267                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20268                            // Note: the background settle time is in elapsed realtime, while
20269                            // the handler time base is uptime.  All this means is that we may
20270                            // stop background uids later than we had intended, but that only
20271                            // happens because the device was sleeping so we are okay anyway.
20272                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20273                        }
20274                    }
20275                } else {
20276                    if (uidRec.idle) {
20277                        uidChange = UidRecord.CHANGE_ACTIVE;
20278                        uidRec.idle = false;
20279                    }
20280                    uidRec.lastBackgroundTime = 0;
20281                }
20282                uidRec.setProcState = uidRec.curProcState;
20283                enqueueUidChangeLocked(uidRec, -1, uidChange);
20284                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20285            }
20286        }
20287
20288        if (mProcessStats.shouldWriteNowLocked(now)) {
20289            mHandler.post(new Runnable() {
20290                @Override public void run() {
20291                    synchronized (ActivityManagerService.this) {
20292                        mProcessStats.writeStateAsyncLocked();
20293                    }
20294                }
20295            });
20296        }
20297
20298        if (DEBUG_OOM_ADJ) {
20299            final long duration = SystemClock.uptimeMillis() - now;
20300            if (false) {
20301                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20302                        new RuntimeException("here").fillInStackTrace());
20303            } else {
20304                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20305            }
20306        }
20307    }
20308
20309    final void idleUids() {
20310        synchronized (this) {
20311            final long nowElapsed = SystemClock.elapsedRealtime();
20312            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20313            long nextTime = 0;
20314            for (int i=mActiveUids.size()-1; i>=0; i--) {
20315                final UidRecord uidRec = mActiveUids.valueAt(i);
20316                final long bgTime = uidRec.lastBackgroundTime;
20317                if (bgTime > 0 && !uidRec.idle) {
20318                    if (bgTime <= maxBgTime) {
20319                        uidRec.idle = true;
20320                        doStopUidLocked(uidRec.uid, uidRec);
20321                    } else {
20322                        if (nextTime == 0 || nextTime > bgTime) {
20323                            nextTime = bgTime;
20324                        }
20325                    }
20326                }
20327            }
20328            if (nextTime > 0) {
20329                mHandler.removeMessages(IDLE_UIDS_MSG);
20330                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20331                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20332            }
20333        }
20334    }
20335
20336    final void runInBackgroundDisabled(int uid) {
20337        synchronized (this) {
20338            UidRecord uidRec = mActiveUids.get(uid);
20339            if (uidRec != null) {
20340                // This uid is actually running...  should it be considered background now?
20341                if (uidRec.idle) {
20342                    doStopUidLocked(uidRec.uid, uidRec);
20343                }
20344            } else {
20345                // This uid isn't actually running...  still send a report about it being "stopped".
20346                doStopUidLocked(uid, null);
20347            }
20348        }
20349    }
20350
20351    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20352        mServices.stopInBackgroundLocked(uid);
20353        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20354    }
20355
20356    final void trimApplications() {
20357        synchronized (this) {
20358            int i;
20359
20360            // First remove any unused application processes whose package
20361            // has been removed.
20362            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20363                final ProcessRecord app = mRemovedProcesses.get(i);
20364                if (app.activities.size() == 0
20365                        && app.curReceiver == null && app.services.size() == 0) {
20366                    Slog.i(
20367                        TAG, "Exiting empty application process "
20368                        + app.processName + " ("
20369                        + (app.thread != null ? app.thread.asBinder() : null)
20370                        + ")\n");
20371                    if (app.pid > 0 && app.pid != MY_PID) {
20372                        app.kill("empty", false);
20373                    } else {
20374                        try {
20375                            app.thread.scheduleExit();
20376                        } catch (Exception e) {
20377                            // Ignore exceptions.
20378                        }
20379                    }
20380                    cleanUpApplicationRecordLocked(app, false, true, -1);
20381                    mRemovedProcesses.remove(i);
20382
20383                    if (app.persistent) {
20384                        addAppLocked(app.info, false, null /* ABI override */);
20385                    }
20386                }
20387            }
20388
20389            // Now update the oom adj for all processes.
20390            updateOomAdjLocked();
20391        }
20392    }
20393
20394    /** This method sends the specified signal to each of the persistent apps */
20395    public void signalPersistentProcesses(int sig) throws RemoteException {
20396        if (sig != Process.SIGNAL_USR1) {
20397            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20398        }
20399
20400        synchronized (this) {
20401            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20402                    != PackageManager.PERMISSION_GRANTED) {
20403                throw new SecurityException("Requires permission "
20404                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20405            }
20406
20407            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20408                ProcessRecord r = mLruProcesses.get(i);
20409                if (r.thread != null && r.persistent) {
20410                    Process.sendSignal(r.pid, sig);
20411                }
20412            }
20413        }
20414    }
20415
20416    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20417        if (proc == null || proc == mProfileProc) {
20418            proc = mProfileProc;
20419            profileType = mProfileType;
20420            clearProfilerLocked();
20421        }
20422        if (proc == null) {
20423            return;
20424        }
20425        try {
20426            proc.thread.profilerControl(false, null, profileType);
20427        } catch (RemoteException e) {
20428            throw new IllegalStateException("Process disappeared");
20429        }
20430    }
20431
20432    private void clearProfilerLocked() {
20433        if (mProfileFd != null) {
20434            try {
20435                mProfileFd.close();
20436            } catch (IOException e) {
20437            }
20438        }
20439        mProfileApp = null;
20440        mProfileProc = null;
20441        mProfileFile = null;
20442        mProfileType = 0;
20443        mAutoStopProfiler = false;
20444        mSamplingInterval = 0;
20445    }
20446
20447    public boolean profileControl(String process, int userId, boolean start,
20448            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20449
20450        try {
20451            synchronized (this) {
20452                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20453                // its own permission.
20454                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20455                        != PackageManager.PERMISSION_GRANTED) {
20456                    throw new SecurityException("Requires permission "
20457                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20458                }
20459
20460                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20461                    throw new IllegalArgumentException("null profile info or fd");
20462                }
20463
20464                ProcessRecord proc = null;
20465                if (process != null) {
20466                    proc = findProcessLocked(process, userId, "profileControl");
20467                }
20468
20469                if (start && (proc == null || proc.thread == null)) {
20470                    throw new IllegalArgumentException("Unknown process: " + process);
20471                }
20472
20473                if (start) {
20474                    stopProfilerLocked(null, 0);
20475                    setProfileApp(proc.info, proc.processName, profilerInfo);
20476                    mProfileProc = proc;
20477                    mProfileType = profileType;
20478                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20479                    try {
20480                        fd = fd.dup();
20481                    } catch (IOException e) {
20482                        fd = null;
20483                    }
20484                    profilerInfo.profileFd = fd;
20485                    proc.thread.profilerControl(start, profilerInfo, profileType);
20486                    fd = null;
20487                    mProfileFd = null;
20488                } else {
20489                    stopProfilerLocked(proc, profileType);
20490                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20491                        try {
20492                            profilerInfo.profileFd.close();
20493                        } catch (IOException e) {
20494                        }
20495                    }
20496                }
20497
20498                return true;
20499            }
20500        } catch (RemoteException e) {
20501            throw new IllegalStateException("Process disappeared");
20502        } finally {
20503            if (profilerInfo != null && profilerInfo.profileFd != null) {
20504                try {
20505                    profilerInfo.profileFd.close();
20506                } catch (IOException e) {
20507                }
20508            }
20509        }
20510    }
20511
20512    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20513        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20514                userId, true, ALLOW_FULL_ONLY, callName, null);
20515        ProcessRecord proc = null;
20516        try {
20517            int pid = Integer.parseInt(process);
20518            synchronized (mPidsSelfLocked) {
20519                proc = mPidsSelfLocked.get(pid);
20520            }
20521        } catch (NumberFormatException e) {
20522        }
20523
20524        if (proc == null) {
20525            ArrayMap<String, SparseArray<ProcessRecord>> all
20526                    = mProcessNames.getMap();
20527            SparseArray<ProcessRecord> procs = all.get(process);
20528            if (procs != null && procs.size() > 0) {
20529                proc = procs.valueAt(0);
20530                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20531                    for (int i=1; i<procs.size(); i++) {
20532                        ProcessRecord thisProc = procs.valueAt(i);
20533                        if (thisProc.userId == userId) {
20534                            proc = thisProc;
20535                            break;
20536                        }
20537                    }
20538                }
20539            }
20540        }
20541
20542        return proc;
20543    }
20544
20545    public boolean dumpHeap(String process, int userId, boolean managed,
20546            String path, ParcelFileDescriptor fd) throws RemoteException {
20547
20548        try {
20549            synchronized (this) {
20550                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20551                // its own permission (same as profileControl).
20552                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20553                        != PackageManager.PERMISSION_GRANTED) {
20554                    throw new SecurityException("Requires permission "
20555                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20556                }
20557
20558                if (fd == null) {
20559                    throw new IllegalArgumentException("null fd");
20560                }
20561
20562                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20563                if (proc == null || proc.thread == null) {
20564                    throw new IllegalArgumentException("Unknown process: " + process);
20565                }
20566
20567                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20568                if (!isDebuggable) {
20569                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20570                        throw new SecurityException("Process not debuggable: " + proc);
20571                    }
20572                }
20573
20574                proc.thread.dumpHeap(managed, path, fd);
20575                fd = null;
20576                return true;
20577            }
20578        } catch (RemoteException e) {
20579            throw new IllegalStateException("Process disappeared");
20580        } finally {
20581            if (fd != null) {
20582                try {
20583                    fd.close();
20584                } catch (IOException e) {
20585                }
20586            }
20587        }
20588    }
20589
20590    @Override
20591    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20592            String reportPackage) {
20593        if (processName != null) {
20594            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20595                    "setDumpHeapDebugLimit()");
20596        } else {
20597            synchronized (mPidsSelfLocked) {
20598                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20599                if (proc == null) {
20600                    throw new SecurityException("No process found for calling pid "
20601                            + Binder.getCallingPid());
20602                }
20603                if (!Build.IS_DEBUGGABLE
20604                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20605                    throw new SecurityException("Not running a debuggable build");
20606                }
20607                processName = proc.processName;
20608                uid = proc.uid;
20609                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20610                    throw new SecurityException("Package " + reportPackage + " is not running in "
20611                            + proc);
20612                }
20613            }
20614        }
20615        synchronized (this) {
20616            if (maxMemSize > 0) {
20617                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20618            } else {
20619                if (uid != 0) {
20620                    mMemWatchProcesses.remove(processName, uid);
20621                } else {
20622                    mMemWatchProcesses.getMap().remove(processName);
20623                }
20624            }
20625        }
20626    }
20627
20628    @Override
20629    public void dumpHeapFinished(String path) {
20630        synchronized (this) {
20631            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20632                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20633                        + " does not match last pid " + mMemWatchDumpPid);
20634                return;
20635            }
20636            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20637                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20638                        + " does not match last path " + mMemWatchDumpFile);
20639                return;
20640            }
20641            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20642            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20643        }
20644    }
20645
20646    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20647    public void monitor() {
20648        synchronized (this) { }
20649    }
20650
20651    void onCoreSettingsChange(Bundle settings) {
20652        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20653            ProcessRecord processRecord = mLruProcesses.get(i);
20654            try {
20655                if (processRecord.thread != null) {
20656                    processRecord.thread.setCoreSettings(settings);
20657                }
20658            } catch (RemoteException re) {
20659                /* ignore */
20660            }
20661        }
20662    }
20663
20664    // Multi-user methods
20665
20666    /**
20667     * Start user, if its not already running, but don't bring it to foreground.
20668     */
20669    @Override
20670    public boolean startUserInBackground(final int userId) {
20671        return mUserController.startUser(userId, /* foreground */ false);
20672    }
20673
20674    @Override
20675    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20676        return mUserController.unlockUser(userId, token, secret, listener);
20677    }
20678
20679    @Override
20680    public boolean switchUser(final int targetUserId) {
20681        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20682        UserInfo currentUserInfo;
20683        UserInfo targetUserInfo;
20684        synchronized (this) {
20685            int currentUserId = mUserController.getCurrentUserIdLocked();
20686            currentUserInfo = mUserController.getUserInfo(currentUserId);
20687            targetUserInfo = mUserController.getUserInfo(targetUserId);
20688            if (targetUserInfo == null) {
20689                Slog.w(TAG, "No user info for user #" + targetUserId);
20690                return false;
20691            }
20692            if (!targetUserInfo.supportsSwitchTo()) {
20693                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20694                return false;
20695            }
20696            if (targetUserInfo.isManagedProfile()) {
20697                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20698                return false;
20699            }
20700            mUserController.setTargetUserIdLocked(targetUserId);
20701        }
20702        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20703        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20704        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20705        return true;
20706    }
20707
20708    void scheduleStartProfilesLocked() {
20709        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20710            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20711                    DateUtils.SECOND_IN_MILLIS);
20712        }
20713    }
20714
20715    @Override
20716    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20717        return mUserController.stopUser(userId, force, callback);
20718    }
20719
20720    @Override
20721    public UserInfo getCurrentUser() {
20722        return mUserController.getCurrentUser();
20723    }
20724
20725    @Override
20726    public boolean isUserRunning(int userId, int flags) {
20727        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20728                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20729            String msg = "Permission Denial: isUserRunning() from pid="
20730                    + Binder.getCallingPid()
20731                    + ", uid=" + Binder.getCallingUid()
20732                    + " requires " + INTERACT_ACROSS_USERS;
20733            Slog.w(TAG, msg);
20734            throw new SecurityException(msg);
20735        }
20736        synchronized (this) {
20737            return mUserController.isUserRunningLocked(userId, flags);
20738        }
20739    }
20740
20741    @Override
20742    public int[] getRunningUserIds() {
20743        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20744                != PackageManager.PERMISSION_GRANTED) {
20745            String msg = "Permission Denial: isUserRunning() from pid="
20746                    + Binder.getCallingPid()
20747                    + ", uid=" + Binder.getCallingUid()
20748                    + " requires " + INTERACT_ACROSS_USERS;
20749            Slog.w(TAG, msg);
20750            throw new SecurityException(msg);
20751        }
20752        synchronized (this) {
20753            return mUserController.getStartedUserArrayLocked();
20754        }
20755    }
20756
20757    @Override
20758    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20759        mUserController.registerUserSwitchObserver(observer);
20760    }
20761
20762    @Override
20763    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20764        mUserController.unregisterUserSwitchObserver(observer);
20765    }
20766
20767    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20768        if (info == null) return null;
20769        ApplicationInfo newInfo = new ApplicationInfo(info);
20770        newInfo.initForUser(userId);
20771        return newInfo;
20772    }
20773
20774    public boolean isUserStopped(int userId) {
20775        synchronized (this) {
20776            return mUserController.getStartedUserStateLocked(userId) == null;
20777        }
20778    }
20779
20780    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20781        if (aInfo == null
20782                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20783            return aInfo;
20784        }
20785
20786        ActivityInfo info = new ActivityInfo(aInfo);
20787        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20788        return info;
20789    }
20790
20791    private boolean processSanityChecksLocked(ProcessRecord process) {
20792        if (process == null || process.thread == null) {
20793            return false;
20794        }
20795
20796        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20797        if (!isDebuggable) {
20798            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20799                return false;
20800            }
20801        }
20802
20803        return true;
20804    }
20805
20806    public boolean startBinderTracking() throws RemoteException {
20807        synchronized (this) {
20808            mBinderTransactionTrackingEnabled = true;
20809            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20810            // permission (same as profileControl).
20811            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20812                    != PackageManager.PERMISSION_GRANTED) {
20813                throw new SecurityException("Requires permission "
20814                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20815            }
20816
20817            for (int i = 0; i < mLruProcesses.size(); i++) {
20818                ProcessRecord process = mLruProcesses.get(i);
20819                if (!processSanityChecksLocked(process)) {
20820                    continue;
20821                }
20822                try {
20823                    process.thread.startBinderTracking();
20824                } catch (RemoteException e) {
20825                    Log.v(TAG, "Process disappared");
20826                }
20827            }
20828            return true;
20829        }
20830    }
20831
20832    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20833        try {
20834            synchronized (this) {
20835                mBinderTransactionTrackingEnabled = false;
20836                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20837                // permission (same as profileControl).
20838                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20839                        != PackageManager.PERMISSION_GRANTED) {
20840                    throw new SecurityException("Requires permission "
20841                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20842                }
20843
20844                if (fd == null) {
20845                    throw new IllegalArgumentException("null fd");
20846                }
20847
20848                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20849                pw.println("Binder transaction traces for all processes.\n");
20850                for (ProcessRecord process : mLruProcesses) {
20851                    if (!processSanityChecksLocked(process)) {
20852                        continue;
20853                    }
20854
20855                    pw.println("Traces for process: " + process.processName);
20856                    pw.flush();
20857                    try {
20858                        TransferPipe tp = new TransferPipe();
20859                        try {
20860                            process.thread.stopBinderTrackingAndDump(
20861                                    tp.getWriteFd().getFileDescriptor());
20862                            tp.go(fd.getFileDescriptor());
20863                        } finally {
20864                            tp.kill();
20865                        }
20866                    } catch (IOException e) {
20867                        pw.println("Failure while dumping IPC traces from " + process +
20868                                ".  Exception: " + e);
20869                        pw.flush();
20870                    } catch (RemoteException e) {
20871                        pw.println("Got a RemoteException while dumping IPC traces from " +
20872                                process + ".  Exception: " + e);
20873                        pw.flush();
20874                    }
20875                }
20876                fd = null;
20877                return true;
20878            }
20879        } finally {
20880            if (fd != null) {
20881                try {
20882                    fd.close();
20883                } catch (IOException e) {
20884                }
20885            }
20886        }
20887    }
20888
20889    private final class LocalService extends ActivityManagerInternal {
20890        @Override
20891        public void onWakefulnessChanged(int wakefulness) {
20892            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20893        }
20894
20895        @Override
20896        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20897                String processName, String abiOverride, int uid, Runnable crashHandler) {
20898            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20899                    processName, abiOverride, uid, crashHandler);
20900        }
20901
20902        @Override
20903        public SleepToken acquireSleepToken(String tag) {
20904            Preconditions.checkNotNull(tag);
20905
20906            synchronized (ActivityManagerService.this) {
20907                SleepTokenImpl token = new SleepTokenImpl(tag);
20908                mSleepTokens.add(token);
20909                updateSleepIfNeededLocked();
20910                applyVrModeIfNeededLocked(mFocusedActivity, false);
20911                return token;
20912            }
20913        }
20914
20915        @Override
20916        public ComponentName getHomeActivityForUser(int userId) {
20917            synchronized (ActivityManagerService.this) {
20918                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20919                return homeActivity == null ? null : homeActivity.realActivity;
20920            }
20921        }
20922
20923        @Override
20924        public void onUserRemoved(int userId) {
20925            synchronized (ActivityManagerService.this) {
20926                ActivityManagerService.this.onUserStoppedLocked(userId);
20927            }
20928        }
20929
20930        @Override
20931        public void onLocalVoiceInteractionStarted(IBinder activity,
20932                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20933            synchronized (ActivityManagerService.this) {
20934                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20935                        voiceSession, voiceInteractor);
20936            }
20937        }
20938
20939        @Override
20940        public void notifyStartingWindowDrawn() {
20941            synchronized (ActivityManagerService.this) {
20942                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20943            }
20944        }
20945
20946        @Override
20947        public void notifyAppTransitionStarting(int reason) {
20948            synchronized (ActivityManagerService.this) {
20949                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20950            }
20951        }
20952
20953        @Override
20954        public void notifyAppTransitionFinished() {
20955            synchronized (ActivityManagerService.this) {
20956                mStackSupervisor.notifyAppTransitionDone();
20957            }
20958        }
20959
20960        @Override
20961        public void notifyAppTransitionCancelled() {
20962            synchronized (ActivityManagerService.this) {
20963                mStackSupervisor.notifyAppTransitionDone();
20964            }
20965        }
20966
20967        @Override
20968        public List<IBinder> getTopVisibleActivities() {
20969            synchronized (ActivityManagerService.this) {
20970                return mStackSupervisor.getTopVisibleActivities();
20971            }
20972        }
20973
20974        @Override
20975        public void notifyDockedStackMinimizedChanged(boolean minimized) {
20976            synchronized (ActivityManagerService.this) {
20977                mStackSupervisor.setDockedStackMinimized(minimized);
20978            }
20979        }
20980    }
20981
20982    private final class SleepTokenImpl extends SleepToken {
20983        private final String mTag;
20984        private final long mAcquireTime;
20985
20986        public SleepTokenImpl(String tag) {
20987            mTag = tag;
20988            mAcquireTime = SystemClock.uptimeMillis();
20989        }
20990
20991        @Override
20992        public void release() {
20993            synchronized (ActivityManagerService.this) {
20994                if (mSleepTokens.remove(this)) {
20995                    updateSleepIfNeededLocked();
20996                }
20997            }
20998        }
20999
21000        @Override
21001        public String toString() {
21002            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21003        }
21004    }
21005
21006    /**
21007     * An implementation of IAppTask, that allows an app to manage its own tasks via
21008     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21009     * only the process that calls getAppTasks() can call the AppTask methods.
21010     */
21011    class AppTaskImpl extends IAppTask.Stub {
21012        private int mTaskId;
21013        private int mCallingUid;
21014
21015        public AppTaskImpl(int taskId, int callingUid) {
21016            mTaskId = taskId;
21017            mCallingUid = callingUid;
21018        }
21019
21020        private void checkCaller() {
21021            if (mCallingUid != Binder.getCallingUid()) {
21022                throw new SecurityException("Caller " + mCallingUid
21023                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21024            }
21025        }
21026
21027        @Override
21028        public void finishAndRemoveTask() {
21029            checkCaller();
21030
21031            synchronized (ActivityManagerService.this) {
21032                long origId = Binder.clearCallingIdentity();
21033                try {
21034                    // We remove the task from recents to preserve backwards
21035                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21036                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21037                    }
21038                } finally {
21039                    Binder.restoreCallingIdentity(origId);
21040                }
21041            }
21042        }
21043
21044        @Override
21045        public ActivityManager.RecentTaskInfo getTaskInfo() {
21046            checkCaller();
21047
21048            synchronized (ActivityManagerService.this) {
21049                long origId = Binder.clearCallingIdentity();
21050                try {
21051                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21052                    if (tr == null) {
21053                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21054                    }
21055                    return createRecentTaskInfoFromTaskRecord(tr);
21056                } finally {
21057                    Binder.restoreCallingIdentity(origId);
21058                }
21059            }
21060        }
21061
21062        @Override
21063        public void moveToFront() {
21064            checkCaller();
21065            // Will bring task to front if it already has a root activity.
21066            final long origId = Binder.clearCallingIdentity();
21067            try {
21068                synchronized (this) {
21069                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21070                }
21071            } finally {
21072                Binder.restoreCallingIdentity(origId);
21073            }
21074        }
21075
21076        @Override
21077        public int startActivity(IBinder whoThread, String callingPackage,
21078                Intent intent, String resolvedType, Bundle bOptions) {
21079            checkCaller();
21080
21081            int callingUser = UserHandle.getCallingUserId();
21082            TaskRecord tr;
21083            IApplicationThread appThread;
21084            synchronized (ActivityManagerService.this) {
21085                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21086                if (tr == null) {
21087                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21088                }
21089                appThread = ApplicationThreadNative.asInterface(whoThread);
21090                if (appThread == null) {
21091                    throw new IllegalArgumentException("Bad app thread " + appThread);
21092                }
21093            }
21094            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21095                    resolvedType, null, null, null, null, 0, 0, null, null,
21096                    null, bOptions, false, callingUser, null, tr);
21097        }
21098
21099        @Override
21100        public void setExcludeFromRecents(boolean exclude) {
21101            checkCaller();
21102
21103            synchronized (ActivityManagerService.this) {
21104                long origId = Binder.clearCallingIdentity();
21105                try {
21106                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21107                    if (tr == null) {
21108                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21109                    }
21110                    Intent intent = tr.getBaseIntent();
21111                    if (exclude) {
21112                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21113                    } else {
21114                        intent.setFlags(intent.getFlags()
21115                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21116                    }
21117                } finally {
21118                    Binder.restoreCallingIdentity(origId);
21119                }
21120            }
21121        }
21122    }
21123
21124    /**
21125     * Kill processes for the user with id userId and that depend on the package named packageName
21126     */
21127    @Override
21128    public void killPackageDependents(String packageName, int userId) {
21129        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21130        if (packageName == null) {
21131            throw new NullPointerException(
21132                    "Cannot kill the dependents of a package without its name.");
21133        }
21134
21135        long callingId = Binder.clearCallingIdentity();
21136        IPackageManager pm = AppGlobals.getPackageManager();
21137        int pkgUid = -1;
21138        try {
21139            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21140        } catch (RemoteException e) {
21141        }
21142        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21143            throw new IllegalArgumentException(
21144                    "Cannot kill dependents of non-existing package " + packageName);
21145        }
21146        try {
21147            synchronized(this) {
21148                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21149                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21150                        "dep: " + packageName);
21151            }
21152        } finally {
21153            Binder.restoreCallingIdentity(callingId);
21154        }
21155    }
21156}
21157