ActivityManagerService.java revision e4fbd328f83ea0ee086731f852cd6c56a3deb733
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.ProcessStats;
30import com.android.internal.app.SystemUserHomeActivity;
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.server.AppOpsService;
44import com.android.server.AttributeCache;
45import com.android.server.DeviceIdleController;
46import com.android.server.IntentResolver;
47import com.android.server.LocalServices;
48import com.android.server.ServiceThread;
49import com.android.server.SystemService;
50import com.android.server.SystemServiceManager;
51import com.android.server.Watchdog;
52import com.android.server.am.ActivityStack.ActivityState;
53import com.android.server.firewall.IntentFirewall;
54import com.android.server.pm.Installer;
55import com.android.server.statusbar.StatusBarManagerInternal;
56import com.android.server.vr.VrManagerInternal;
57import com.android.server.wm.AppTransition;
58import com.android.server.wm.WindowManagerService;
59
60import org.xmlpull.v1.XmlPullParser;
61import org.xmlpull.v1.XmlPullParserException;
62import org.xmlpull.v1.XmlSerializer;
63
64import android.Manifest;
65import android.app.Activity;
66import android.app.ActivityManager;
67import android.app.ActivityManager.RunningTaskInfo;
68import android.app.ActivityManager.StackId;
69import android.app.ActivityManager.StackInfo;
70import android.app.ActivityManager.TaskThumbnailInfo;
71import android.app.ActivityManagerInternal;
72import android.app.ActivityManagerInternal.SleepToken;
73import android.app.ActivityManagerNative;
74import android.app.ActivityOptions;
75import android.app.ActivityThread;
76import android.app.AlertDialog;
77import android.app.AppGlobals;
78import android.app.AppOpsManager;
79import android.app.ApplicationErrorReport;
80import android.app.ApplicationThreadNative;
81import android.app.BroadcastOptions;
82import android.app.Dialog;
83import android.app.IActivityContainer;
84import android.app.IActivityContainerCallback;
85import android.app.IActivityController;
86import android.app.IAppTask;
87import android.app.IApplicationThread;
88import android.app.IInstrumentationWatcher;
89import android.app.INotificationManager;
90import android.app.IProcessObserver;
91import android.app.IServiceConnection;
92import android.app.IStopUserCallback;
93import android.app.ITaskStackListener;
94import android.app.IUiAutomationConnection;
95import android.app.IUidObserver;
96import android.app.IUserSwitchObserver;
97import android.app.Instrumentation;
98import android.app.Notification;
99import android.app.NotificationManager;
100import android.app.PendingIntent;
101import android.app.ProfilerInfo;
102import android.app.admin.DevicePolicyManager;
103import android.app.assist.AssistContent;
104import android.app.assist.AssistStructure;
105import android.app.backup.IBackupManager;
106import android.app.usage.UsageEvents;
107import android.app.usage.UsageStatsManagerInternal;
108import android.appwidget.AppWidgetManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.PackageManager.NameNotFoundException;
133import android.content.pm.PackageManagerInternal;
134import android.content.pm.ParceledListSlice;
135import android.content.pm.PathPermission;
136import android.content.pm.PermissionInfo;
137import android.content.pm.ProviderInfo;
138import android.content.pm.ResolveInfo;
139import android.content.pm.ServiceInfo;
140import android.content.pm.UserInfo;
141import android.content.res.CompatibilityInfo;
142import android.content.res.Configuration;
143import android.content.res.Resources;
144import android.database.ContentObserver;
145import android.graphics.Bitmap;
146import android.graphics.Point;
147import android.graphics.Rect;
148import android.location.LocationManager;
149import android.net.Proxy;
150import android.net.ProxyInfo;
151import android.net.Uri;
152import android.os.BatteryStats;
153import android.os.Binder;
154import android.os.Build;
155import android.os.Bundle;
156import android.os.Debug;
157import android.os.DropBoxManager;
158import android.os.Environment;
159import android.os.FactoryTest;
160import android.os.FileObserver;
161import android.os.FileUtils;
162import android.os.Handler;
163import android.os.IBinder;
164import android.os.IPermissionController;
165import android.os.IProcessInfoService;
166import android.os.Looper;
167import android.os.Message;
168import android.os.Parcel;
169import android.os.ParcelFileDescriptor;
170import android.os.PersistableBundle;
171import android.os.PowerManager;
172import android.os.PowerManagerInternal;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.ResultReceiver;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.Trace;
182import android.os.TransactionTooLargeException;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.os.WorkSource;
187import android.os.storage.IMountService;
188import android.os.storage.MountServiceInternal;
189import android.os.storage.StorageManager;
190import android.provider.Settings;
191import android.service.voice.IVoiceInteractionSession;
192import android.service.voice.VoiceInteractionManagerInternal;
193import android.service.voice.VoiceInteractionSession;
194import android.text.format.DateUtils;
195import android.text.format.Time;
196import android.util.ArrayMap;
197import android.util.ArraySet;
198import android.util.AtomicFile;
199import android.util.DebugUtils;
200import android.util.EventLog;
201import android.util.LocaleList;
202import android.util.Log;
203import android.util.Pair;
204import android.util.PrintWriterPrinter;
205import android.util.Slog;
206import android.util.SparseArray;
207import android.util.TimeUtils;
208import android.util.Xml;
209import android.view.Display;
210import android.view.Gravity;
211import android.view.LayoutInflater;
212import android.view.View;
213import android.view.WindowManager;
214
215import java.io.BufferedInputStream;
216import java.io.BufferedOutputStream;
217import java.io.DataInputStream;
218import java.io.DataOutputStream;
219import java.io.File;
220import java.io.FileDescriptor;
221import java.io.FileInputStream;
222import java.io.FileNotFoundException;
223import java.io.FileOutputStream;
224import java.io.IOException;
225import java.io.InputStreamReader;
226import java.io.PrintWriter;
227import java.io.StringWriter;
228import java.lang.ref.WeakReference;
229import java.nio.charset.StandardCharsets;
230import java.util.ArrayList;
231import java.util.Arrays;
232import java.util.Collections;
233import java.util.Comparator;
234import java.util.HashMap;
235import java.util.HashSet;
236import java.util.Iterator;
237import java.util.List;
238import java.util.Locale;
239import java.util.Map;
240import java.util.Set;
241import java.util.concurrent.atomic.AtomicBoolean;
242import java.util.concurrent.atomic.AtomicLong;
243
244import dalvik.system.VMRuntime;
245
246import libcore.io.IoUtils;
247import libcore.util.EmptyArray;
248
249import static android.Manifest.permission.INTERACT_ACROSS_USERS;
250import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
251import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
252import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
253import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
254import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
255import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
256import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
257import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
258import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.HOME_STACK_ID;
260import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
261import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
263import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
264import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
265import static android.content.pm.PackageManager.GET_PROVIDERS;
266import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
267import static android.content.pm.PackageManager.MATCH_ENCRYPTION_UNAWARE;
268import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
269import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
270import static android.content.pm.PackageManager.PERMISSION_GRANTED;
271import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
272import static android.provider.Settings.Global.DEBUG_APP;
273import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
274import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
276import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
277import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
278import static android.provider.Settings.System.FONT_SCALE;
279import static com.android.internal.util.XmlUtils.readBooleanAttribute;
280import static com.android.internal.util.XmlUtils.readIntAttribute;
281import static com.android.internal.util.XmlUtils.readLongAttribute;
282import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
283import static com.android.internal.util.XmlUtils.writeIntAttribute;
284import static com.android.internal.util.XmlUtils.writeLongAttribute;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
340import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
341import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
342import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
343import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
344import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
345import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
346import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
347import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
348import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
349import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
350import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
351import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
352import static org.xmlpull.v1.XmlPullParser.START_TAG;
353
354public final class ActivityManagerService extends ActivityManagerNative
355        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
356
357    // File that stores last updated system version and called preboot receivers
358    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
359
360    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
361    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
362    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
363    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
364    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
365    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
366    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
367    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
368    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
369    private static final String TAG_LRU = TAG + POSTFIX_LRU;
370    private static final String TAG_MU = TAG + POSTFIX_MU;
371    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
372    private static final String TAG_POWER = TAG + POSTFIX_POWER;
373    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
374    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
375    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
376    private static final String TAG_PSS = TAG + POSTFIX_PSS;
377    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
378    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
379    private static final String TAG_STACK = TAG + POSTFIX_STACK;
380    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
381    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
382    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
383    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
384    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
385
386    /** Control over CPU and battery monitoring */
387    // write battery stats every 30 minutes.
388    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
389    static final boolean MONITOR_CPU_USAGE = true;
390    // don't sample cpu less than every 5 seconds.
391    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
392    // wait possibly forever for next cpu sample.
393    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
394    static final boolean MONITOR_THREAD_CPU_USAGE = false;
395
396    // The flags that are set for all calls we make to the package manager.
397    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
398
399    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
400
401    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
402
403    // Amount of time after a call to stopAppSwitches() during which we will
404    // prevent further untrusted switches from happening.
405    static final long APP_SWITCH_DELAY_TIME = 5*1000;
406
407    // How long we wait for a launched process to attach to the activity manager
408    // before we decide it's never going to come up for real.
409    static final int PROC_START_TIMEOUT = 10*1000;
410    // How long we wait for an attached process to publish its content providers
411    // before we decide it must be hung.
412    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
413
414    // How long we will retain processes hosting content providers in the "last activity"
415    // state before allowing them to drop down to the regular cached LRU list.  This is
416    // to avoid thrashing of provider processes under low memory situations.
417    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
418
419    // How long we wait for a launched process to attach to the activity manager
420    // before we decide it's never going to come up for real, when the process was
421    // started with a wrapper for instrumentation (such as Valgrind) because it
422    // could take much longer than usual.
423    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
424
425    // How long to wait after going idle before forcing apps to GC.
426    static final int GC_TIMEOUT = 5*1000;
427
428    // The minimum amount of time between successive GC requests for a process.
429    static final int GC_MIN_INTERVAL = 60*1000;
430
431    // The minimum amount of time between successive PSS requests for a process.
432    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
433
434    // The minimum amount of time between successive PSS requests for a process
435    // when the request is due to the memory state being lowered.
436    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
437
438    // The rate at which we check for apps using excessive power -- 15 mins.
439    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
440
441    // The minimum sample duration we will allow before deciding we have
442    // enough data on wake locks to start killing things.
443    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
444
445    // The minimum sample duration we will allow before deciding we have
446    // enough data on CPU usage to start killing things.
447    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
448
449    // How long we allow a receiver to run before giving up on it.
450    static final int BROADCAST_FG_TIMEOUT = 10*1000;
451    static final int BROADCAST_BG_TIMEOUT = 60*1000;
452
453    // How long we wait until we timeout on key dispatching.
454    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
455
456    // How long we wait until we timeout on key dispatching during instrumentation.
457    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
458
459    // This is the amount of time an app needs to be running a foreground service before
460    // we will consider it to be doing interaction for usage stats.
461    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
462
463    // Maximum amount of time we will allow to elapse before re-reporting usage stats
464    // interaction with foreground processes.
465    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
466
467    // This is the amount of time we allow an app to settle after it goes into the background,
468    // before we start restricting what it can do.
469    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
470
471    // How long to wait in getAssistContextExtras for the activity and foreground services
472    // to respond with the result.
473    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
474
475    // How long top wait when going through the modern assist (which doesn't need to block
476    // on getting this result before starting to launch its UI).
477    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
478
479    // Maximum number of persisted Uri grants a package is allowed
480    static final int MAX_PERSISTED_URI_GRANTS = 128;
481
482    static final int MY_PID = Process.myPid();
483
484    static final String[] EMPTY_STRING_ARRAY = new String[0];
485
486    // How many bytes to write into the dropbox log before truncating
487    static final int DROPBOX_MAX_SIZE = 256 * 1024;
488
489    // Access modes for handleIncomingUser.
490    static final int ALLOW_NON_FULL = 0;
491    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
492    static final int ALLOW_FULL_ONLY = 2;
493
494    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
495
496    // Delay in notifying task stack change listeners (in millis)
497    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
498
499    // Necessary ApplicationInfo flags to mark an app as persistent
500    private static final int PERSISTENT_MASK =
501            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
502
503    // Intent sent when remote bugreport collection has been completed
504    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
505            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
506
507    // Delay to disable app launch boost
508    static final int APP_BOOST_MESSAGE_DELAY = 3000;
509    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
510    static final int APP_BOOST_TIMEOUT = 2500;
511
512    // Used to indicate that a task is removed it should also be removed from recents.
513    private static final boolean REMOVE_FROM_RECENTS = true;
514    // Used to indicate that an app transition should be animated.
515    static final boolean ANIMATE = true;
516
517    // Determines whether to take full screen screenshots
518    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
519
520    private static native int nativeMigrateToBoost();
521    private static native int nativeMigrateFromBoost();
522    private boolean mIsBoosted = false;
523    private long mBoostStartTime = 0;
524
525    /** All system services */
526    SystemServiceManager mSystemServiceManager;
527
528    private Installer mInstaller;
529
530    /** Run all ActivityStacks through this */
531    final ActivityStackSupervisor mStackSupervisor;
532
533    final ActivityStarter mActivityStarter;
534
535    /** Task stack change listeners. */
536    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
537            new RemoteCallbackList<ITaskStackListener>();
538
539    public IntentFirewall mIntentFirewall;
540
541    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
542    // default actuion automatically.  Important for devices without direct input
543    // devices.
544    private boolean mShowDialogs = true;
545    private boolean mInVrMode = false;
546
547    BroadcastQueue mFgBroadcastQueue;
548    BroadcastQueue mBgBroadcastQueue;
549    // Convenient for easy iteration over the queues. Foreground is first
550    // so that dispatch of foreground broadcasts gets precedence.
551    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
552
553    BroadcastQueue broadcastQueueForIntent(Intent intent) {
554        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
555        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
556                "Broadcast intent " + intent + " on "
557                + (isFg ? "foreground" : "background") + " queue");
558        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
559    }
560
561    /**
562     * Activity we have told the window manager to have key focus.
563     */
564    ActivityRecord mFocusedActivity = null;
565
566    /**
567     * User id of the last activity mFocusedActivity was set to.
568     */
569    private int mLastFocusedUserId;
570
571    /**
572     * If non-null, we are tracking the time the user spends in the currently focused app.
573     */
574    private AppTimeTracker mCurAppTimeTracker;
575
576    /**
577     * List of intents that were used to start the most recent tasks.
578     */
579    final RecentTasks mRecentTasks;
580
581    /**
582     * For addAppTask: cached of the last activity component that was added.
583     */
584    ComponentName mLastAddedTaskComponent;
585
586    /**
587     * For addAppTask: cached of the last activity uid that was added.
588     */
589    int mLastAddedTaskUid;
590
591    /**
592     * For addAppTask: cached of the last ActivityInfo that was added.
593     */
594    ActivityInfo mLastAddedTaskActivity;
595
596    /**
597     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
598     */
599    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
600
601    /**
602     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
603     */
604    String mDeviceOwnerName;
605
606    final UserController mUserController;
607
608    final AppErrors mAppErrors;
609
610    boolean mDoingSetFocusedActivity;
611
612    public boolean canShowErrorDialogs() {
613        return mShowDialogs && !mSleeping && !mShuttingDown;
614    }
615
616    public class PendingAssistExtras extends Binder implements Runnable {
617        public final ActivityRecord activity;
618        public final Bundle extras;
619        public final Intent intent;
620        public final String hint;
621        public final IResultReceiver receiver;
622        public final int userHandle;
623        public boolean haveResult = false;
624        public Bundle result = null;
625        public AssistStructure structure = null;
626        public AssistContent content = null;
627        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
628                String _hint, IResultReceiver _receiver, int _userHandle) {
629            activity = _activity;
630            extras = _extras;
631            intent = _intent;
632            hint = _hint;
633            receiver = _receiver;
634            userHandle = _userHandle;
635        }
636        @Override
637        public void run() {
638            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
639            synchronized (this) {
640                haveResult = true;
641                notifyAll();
642            }
643            pendingAssistExtrasTimedOut(this);
644        }
645    }
646
647    final ArrayList<PendingAssistExtras> mPendingAssistExtras
648            = new ArrayList<PendingAssistExtras>();
649
650    /**
651     * Process management.
652     */
653    final ProcessList mProcessList = new ProcessList();
654
655    /**
656     * All of the applications we currently have running organized by name.
657     * The keys are strings of the application package name (as
658     * returned by the package manager), and the keys are ApplicationRecord
659     * objects.
660     */
661    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
662
663    /**
664     * Tracking long-term execution of processes to look for abuse and other
665     * bad app behavior.
666     */
667    final ProcessStatsService mProcessStats;
668
669    /**
670     * The currently running isolated processes.
671     */
672    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
673
674    /**
675     * Counter for assigning isolated process uids, to avoid frequently reusing the
676     * same ones.
677     */
678    int mNextIsolatedProcessUid = 0;
679
680    /**
681     * The currently running heavy-weight process, if any.
682     */
683    ProcessRecord mHeavyWeightProcess = null;
684
685    /**
686     * All of the processes we currently have running organized by pid.
687     * The keys are the pid running the application.
688     *
689     * <p>NOTE: This object is protected by its own lock, NOT the global
690     * activity manager lock!
691     */
692    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
693
694    /**
695     * All of the processes that have been forced to be foreground.  The key
696     * is the pid of the caller who requested it (we hold a death
697     * link on it).
698     */
699    abstract class ForegroundToken implements IBinder.DeathRecipient {
700        int pid;
701        IBinder token;
702    }
703    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
704
705    /**
706     * List of records for processes that someone had tried to start before the
707     * system was ready.  We don't start them at that point, but ensure they
708     * are started by the time booting is complete.
709     */
710    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
711
712    /**
713     * List of persistent applications that are in the process
714     * of being started.
715     */
716    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
717
718    /**
719     * Processes that are being forcibly torn down.
720     */
721    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
722
723    /**
724     * List of running applications, sorted by recent usage.
725     * The first entry in the list is the least recently used.
726     */
727    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
728
729    /**
730     * Where in mLruProcesses that the processes hosting activities start.
731     */
732    int mLruProcessActivityStart = 0;
733
734    /**
735     * Where in mLruProcesses that the processes hosting services start.
736     * This is after (lower index) than mLruProcessesActivityStart.
737     */
738    int mLruProcessServiceStart = 0;
739
740    /**
741     * List of processes that should gc as soon as things are idle.
742     */
743    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
744
745    /**
746     * Processes we want to collect PSS data from.
747     */
748    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
749
750    private boolean mBinderTransactionTrackingEnabled = false;
751
752    /**
753     * Last time we requested PSS data of all processes.
754     */
755    long mLastFullPssTime = SystemClock.uptimeMillis();
756
757    /**
758     * If set, the next time we collect PSS data we should do a full collection
759     * with data from native processes and the kernel.
760     */
761    boolean mFullPssPending = false;
762
763    /**
764     * This is the process holding what we currently consider to be
765     * the "home" activity.
766     */
767    ProcessRecord mHomeProcess;
768
769    /**
770     * This is the process holding the activity the user last visited that
771     * is in a different process from the one they are currently in.
772     */
773    ProcessRecord mPreviousProcess;
774
775    /**
776     * The time at which the previous process was last visible.
777     */
778    long mPreviousProcessVisibleTime;
779
780    /**
781     * Track all uids that have actively running processes.
782     */
783    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
784
785    /**
786     * This is for verifying the UID report flow.
787     */
788    static final boolean VALIDATE_UID_STATES = true;
789    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
790
791    /**
792     * Packages that the user has asked to have run in screen size
793     * compatibility mode instead of filling the screen.
794     */
795    final CompatModePackages mCompatModePackages;
796
797    /**
798     * Set of IntentSenderRecord objects that are currently active.
799     */
800    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
801            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
802
803    /**
804     * Fingerprints (hashCode()) of stack traces that we've
805     * already logged DropBox entries for.  Guarded by itself.  If
806     * something (rogue user app) forces this over
807     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
808     */
809    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
810    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
811
812    /**
813     * Strict Mode background batched logging state.
814     *
815     * The string buffer is guarded by itself, and its lock is also
816     * used to determine if another batched write is already
817     * in-flight.
818     */
819    private final StringBuilder mStrictModeBuffer = new StringBuilder();
820
821    /**
822     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
823     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
824     */
825    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
826
827    /**
828     * Resolver for broadcast intents to registered receivers.
829     * Holds BroadcastFilter (subclass of IntentFilter).
830     */
831    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
832            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
833        @Override
834        protected boolean allowFilterResult(
835                BroadcastFilter filter, List<BroadcastFilter> dest) {
836            IBinder target = filter.receiverList.receiver.asBinder();
837            for (int i = dest.size() - 1; i >= 0; i--) {
838                if (dest.get(i).receiverList.receiver.asBinder() == target) {
839                    return false;
840                }
841            }
842            return true;
843        }
844
845        @Override
846        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
847            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
848                    || userId == filter.owningUserId) {
849                return super.newResult(filter, match, userId);
850            }
851            return null;
852        }
853
854        @Override
855        protected BroadcastFilter[] newArray(int size) {
856            return new BroadcastFilter[size];
857        }
858
859        @Override
860        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
861            return packageName.equals(filter.packageName);
862        }
863    };
864
865    /**
866     * State of all active sticky broadcasts per user.  Keys are the action of the
867     * sticky Intent, values are an ArrayList of all broadcasted intents with
868     * that action (which should usually be one).  The SparseArray is keyed
869     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
870     * for stickies that are sent to all users.
871     */
872    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
873            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
874
875    final ActiveServices mServices;
876
877    final static class Association {
878        final int mSourceUid;
879        final String mSourceProcess;
880        final int mTargetUid;
881        final ComponentName mTargetComponent;
882        final String mTargetProcess;
883
884        int mCount;
885        long mTime;
886
887        int mNesting;
888        long mStartTime;
889
890        Association(int sourceUid, String sourceProcess, int targetUid,
891                ComponentName targetComponent, String targetProcess) {
892            mSourceUid = sourceUid;
893            mSourceProcess = sourceProcess;
894            mTargetUid = targetUid;
895            mTargetComponent = targetComponent;
896            mTargetProcess = targetProcess;
897        }
898    }
899
900    /**
901     * When service association tracking is enabled, this is all of the associations we
902     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
903     * -> association data.
904     */
905    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
906            mAssociations = new SparseArray<>();
907    boolean mTrackingAssociations;
908
909    /**
910     * Backup/restore process management
911     */
912    String mBackupAppName = null;
913    BackupRecord mBackupTarget = null;
914
915    final ProviderMap mProviderMap;
916
917    /**
918     * List of content providers who have clients waiting for them.  The
919     * application is currently being launched and the provider will be
920     * removed from this list once it is published.
921     */
922    final ArrayList<ContentProviderRecord> mLaunchingProviders
923            = new ArrayList<ContentProviderRecord>();
924
925    /**
926     * File storing persisted {@link #mGrantedUriPermissions}.
927     */
928    private final AtomicFile mGrantFile;
929
930    /** XML constants used in {@link #mGrantFile} */
931    private static final String TAG_URI_GRANTS = "uri-grants";
932    private static final String TAG_URI_GRANT = "uri-grant";
933    private static final String ATTR_USER_HANDLE = "userHandle";
934    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
935    private static final String ATTR_TARGET_USER_ID = "targetUserId";
936    private static final String ATTR_SOURCE_PKG = "sourcePkg";
937    private static final String ATTR_TARGET_PKG = "targetPkg";
938    private static final String ATTR_URI = "uri";
939    private static final String ATTR_MODE_FLAGS = "modeFlags";
940    private static final String ATTR_CREATED_TIME = "createdTime";
941    private static final String ATTR_PREFIX = "prefix";
942
943    /**
944     * Global set of specific {@link Uri} permissions that have been granted.
945     * This optimized lookup structure maps from {@link UriPermission#targetUid}
946     * to {@link UriPermission#uri} to {@link UriPermission}.
947     */
948    @GuardedBy("this")
949    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
950            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
951
952    public static class GrantUri {
953        public final int sourceUserId;
954        public final Uri uri;
955        public boolean prefix;
956
957        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
958            this.sourceUserId = sourceUserId;
959            this.uri = uri;
960            this.prefix = prefix;
961        }
962
963        @Override
964        public int hashCode() {
965            int hashCode = 1;
966            hashCode = 31 * hashCode + sourceUserId;
967            hashCode = 31 * hashCode + uri.hashCode();
968            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
969            return hashCode;
970        }
971
972        @Override
973        public boolean equals(Object o) {
974            if (o instanceof GrantUri) {
975                GrantUri other = (GrantUri) o;
976                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
977                        && prefix == other.prefix;
978            }
979            return false;
980        }
981
982        @Override
983        public String toString() {
984            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
985            if (prefix) result += " [prefix]";
986            return result;
987        }
988
989        public String toSafeString() {
990            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
991            if (prefix) result += " [prefix]";
992            return result;
993        }
994
995        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
996            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
997                    ContentProvider.getUriWithoutUserId(uri), false);
998        }
999    }
1000
1001    CoreSettingsObserver mCoreSettingsObserver;
1002
1003    FontScaleSettingObserver mFontScaleSettingObserver;
1004
1005    private final class FontScaleSettingObserver extends ContentObserver {
1006        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1007
1008        public FontScaleSettingObserver() {
1009            super(mHandler);
1010            ContentResolver resolver = mContext.getContentResolver();
1011            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1012        }
1013
1014        @Override
1015        public void onChange(boolean selfChange, Uri uri) {
1016            if (mFontScaleUri.equals(uri)) {
1017                updateFontScaleIfNeeded();
1018            }
1019        }
1020    }
1021
1022    /**
1023     * Thread-local storage used to carry caller permissions over through
1024     * indirect content-provider access.
1025     */
1026    private class Identity {
1027        public final IBinder token;
1028        public final int pid;
1029        public final int uid;
1030
1031        Identity(IBinder _token, int _pid, int _uid) {
1032            token = _token;
1033            pid = _pid;
1034            uid = _uid;
1035        }
1036    }
1037
1038    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1039
1040    /**
1041     * All information we have collected about the runtime performance of
1042     * any user id that can impact battery performance.
1043     */
1044    final BatteryStatsService mBatteryStatsService;
1045
1046    /**
1047     * Information about component usage
1048     */
1049    UsageStatsManagerInternal mUsageStatsService;
1050
1051    /**
1052     * Access to DeviceIdleController service.
1053     */
1054    DeviceIdleController.LocalService mLocalDeviceIdleController;
1055
1056    /**
1057     * Information about and control over application operations
1058     */
1059    final AppOpsService mAppOpsService;
1060
1061    /**
1062     * Current configuration information.  HistoryRecord objects are given
1063     * a reference to this object to indicate which configuration they are
1064     * currently running in, so this object must be kept immutable.
1065     */
1066    Configuration mConfiguration = new Configuration();
1067
1068    /**
1069     * Current sequencing integer of the configuration, for skipping old
1070     * configurations.
1071     */
1072    int mConfigurationSeq = 0;
1073
1074    boolean mSuppressResizeConfigChanges = false;
1075
1076    /**
1077     * Hardware-reported OpenGLES version.
1078     */
1079    final int GL_ES_VERSION;
1080
1081    /**
1082     * List of initialization arguments to pass to all processes when binding applications to them.
1083     * For example, references to the commonly used services.
1084     */
1085    HashMap<String, IBinder> mAppBindArgs;
1086
1087    /**
1088     * Temporary to avoid allocations.  Protected by main lock.
1089     */
1090    final StringBuilder mStringBuilder = new StringBuilder(256);
1091
1092    /**
1093     * Used to control how we initialize the service.
1094     */
1095    ComponentName mTopComponent;
1096    String mTopAction = Intent.ACTION_MAIN;
1097    String mTopData;
1098    boolean mProcessesReady = false;
1099    boolean mSystemReady = false;
1100    boolean mBooting = false;
1101    boolean mCallFinishBooting = false;
1102    boolean mBootAnimationComplete = false;
1103    boolean mWaitingUpdate = false;
1104    boolean mDidUpdate = false;
1105    boolean mOnBattery = false;
1106    boolean mLaunchWarningShown = false;
1107
1108    Context mContext;
1109
1110    int mFactoryTest;
1111
1112    boolean mCheckedForSetup;
1113
1114    /**
1115     * The time at which we will allow normal application switches again,
1116     * after a call to {@link #stopAppSwitches()}.
1117     */
1118    long mAppSwitchesAllowedTime;
1119
1120    /**
1121     * This is set to true after the first switch after mAppSwitchesAllowedTime
1122     * is set; any switches after that will clear the time.
1123     */
1124    boolean mDidAppSwitch;
1125
1126    /**
1127     * Last time (in realtime) at which we checked for power usage.
1128     */
1129    long mLastPowerCheckRealtime;
1130
1131    /**
1132     * Last time (in uptime) at which we checked for power usage.
1133     */
1134    long mLastPowerCheckUptime;
1135
1136    /**
1137     * Set while we are wanting to sleep, to prevent any
1138     * activities from being started/resumed.
1139     */
1140    private boolean mSleeping = false;
1141
1142    /**
1143     * The process state used for processes that are running the top activities.
1144     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1145     */
1146    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1147
1148    /**
1149     * Set while we are running a voice interaction.  This overrides
1150     * sleeping while it is active.
1151     */
1152    private IVoiceInteractionSession mRunningVoice;
1153
1154    /**
1155     * For some direct access we need to power manager.
1156     */
1157    PowerManagerInternal mLocalPowerManager;
1158
1159    /**
1160     * We want to hold a wake lock while running a voice interaction session, since
1161     * this may happen with the screen off and we need to keep the CPU running to
1162     * be able to continue to interact with the user.
1163     */
1164    PowerManager.WakeLock mVoiceWakeLock;
1165
1166    /**
1167     * State of external calls telling us if the device is awake or asleep.
1168     */
1169    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1170
1171    /**
1172     * A list of tokens that cause the top activity to be put to sleep.
1173     * They are used by components that may hide and block interaction with underlying
1174     * activities.
1175     */
1176    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1177
1178    static final int LOCK_SCREEN_HIDDEN = 0;
1179    static final int LOCK_SCREEN_LEAVING = 1;
1180    static final int LOCK_SCREEN_SHOWN = 2;
1181    /**
1182     * State of external call telling us if the lock screen is shown.
1183     */
1184    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1185
1186    /**
1187     * Set if we are shutting down the system, similar to sleeping.
1188     */
1189    boolean mShuttingDown = false;
1190
1191    /**
1192     * Current sequence id for oom_adj computation traversal.
1193     */
1194    int mAdjSeq = 0;
1195
1196    /**
1197     * Current sequence id for process LRU updating.
1198     */
1199    int mLruSeq = 0;
1200
1201    /**
1202     * Keep track of the non-cached/empty process we last found, to help
1203     * determine how to distribute cached/empty processes next time.
1204     */
1205    int mNumNonCachedProcs = 0;
1206
1207    /**
1208     * Keep track of the number of cached hidden procs, to balance oom adj
1209     * distribution between those and empty procs.
1210     */
1211    int mNumCachedHiddenProcs = 0;
1212
1213    /**
1214     * Keep track of the number of service processes we last found, to
1215     * determine on the next iteration which should be B services.
1216     */
1217    int mNumServiceProcs = 0;
1218    int mNewNumAServiceProcs = 0;
1219    int mNewNumServiceProcs = 0;
1220
1221    /**
1222     * Allow the current computed overall memory level of the system to go down?
1223     * This is set to false when we are killing processes for reasons other than
1224     * memory management, so that the now smaller process list will not be taken as
1225     * an indication that memory is tighter.
1226     */
1227    boolean mAllowLowerMemLevel = false;
1228
1229    /**
1230     * The last computed memory level, for holding when we are in a state that
1231     * processes are going away for other reasons.
1232     */
1233    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1234
1235    /**
1236     * The last total number of process we have, to determine if changes actually look
1237     * like a shrinking number of process due to lower RAM.
1238     */
1239    int mLastNumProcesses;
1240
1241    /**
1242     * The uptime of the last time we performed idle maintenance.
1243     */
1244    long mLastIdleTime = SystemClock.uptimeMillis();
1245
1246    /**
1247     * Total time spent with RAM that has been added in the past since the last idle time.
1248     */
1249    long mLowRamTimeSinceLastIdle = 0;
1250
1251    /**
1252     * If RAM is currently low, when that horrible situation started.
1253     */
1254    long mLowRamStartTime = 0;
1255
1256    /**
1257     * For reporting to battery stats the current top application.
1258     */
1259    private String mCurResumedPackage = null;
1260    private int mCurResumedUid = -1;
1261
1262    /**
1263     * For reporting to battery stats the apps currently running foreground
1264     * service.  The ProcessMap is package/uid tuples; each of these contain
1265     * an array of the currently foreground processes.
1266     */
1267    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1268            = new ProcessMap<ArrayList<ProcessRecord>>();
1269
1270    /**
1271     * This is set if we had to do a delayed dexopt of an app before launching
1272     * it, to increase the ANR timeouts in that case.
1273     */
1274    boolean mDidDexOpt;
1275
1276    /**
1277     * Set if the systemServer made a call to enterSafeMode.
1278     */
1279    boolean mSafeMode;
1280
1281    /**
1282     * If true, we are running under a test environment so will sample PSS from processes
1283     * much more rapidly to try to collect better data when the tests are rapidly
1284     * running through apps.
1285     */
1286    boolean mTestPssMode = false;
1287
1288    String mDebugApp = null;
1289    boolean mWaitForDebugger = false;
1290    boolean mDebugTransient = false;
1291    String mOrigDebugApp = null;
1292    boolean mOrigWaitForDebugger = false;
1293    boolean mAlwaysFinishActivities = false;
1294    boolean mLenientBackgroundCheck = false;
1295    boolean mForceResizableActivities;
1296    boolean mSupportsFreeformWindowManagement;
1297    boolean mSupportsPictureInPicture;
1298    Rect mDefaultPinnedStackBounds;
1299    IActivityController mController = null;
1300    String mProfileApp = null;
1301    ProcessRecord mProfileProc = null;
1302    String mProfileFile;
1303    ParcelFileDescriptor mProfileFd;
1304    int mSamplingInterval = 0;
1305    boolean mAutoStopProfiler = false;
1306    int mProfileType = 0;
1307    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1308    String mMemWatchDumpProcName;
1309    String mMemWatchDumpFile;
1310    int mMemWatchDumpPid;
1311    int mMemWatchDumpUid;
1312    String mTrackAllocationApp = null;
1313    String mNativeDebuggingApp = null;
1314
1315    final long[] mTmpLong = new long[2];
1316
1317    static final class ProcessChangeItem {
1318        static final int CHANGE_ACTIVITIES = 1<<0;
1319        static final int CHANGE_PROCESS_STATE = 1<<1;
1320        int changes;
1321        int uid;
1322        int pid;
1323        int processState;
1324        boolean foregroundActivities;
1325    }
1326
1327    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1328    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1329
1330    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1331    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1332
1333    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1334    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1335
1336    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1337    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1338
1339    /**
1340     * Runtime CPU use collection thread.  This object's lock is used to
1341     * perform synchronization with the thread (notifying it to run).
1342     */
1343    final Thread mProcessCpuThread;
1344
1345    /**
1346     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1347     * Must acquire this object's lock when accessing it.
1348     * NOTE: this lock will be held while doing long operations (trawling
1349     * through all processes in /proc), so it should never be acquired by
1350     * any critical paths such as when holding the main activity manager lock.
1351     */
1352    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1353            MONITOR_THREAD_CPU_USAGE);
1354    final AtomicLong mLastCpuTime = new AtomicLong(0);
1355    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1356
1357    long mLastWriteTime = 0;
1358
1359    /**
1360     * Used to retain an update lock when the foreground activity is in
1361     * immersive mode.
1362     */
1363    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1364
1365    /**
1366     * Set to true after the system has finished booting.
1367     */
1368    boolean mBooted = false;
1369
1370    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1371    int mProcessLimitOverride = -1;
1372
1373    WindowManagerService mWindowManager;
1374    final ActivityThread mSystemThread;
1375
1376    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1377        final ProcessRecord mApp;
1378        final int mPid;
1379        final IApplicationThread mAppThread;
1380
1381        AppDeathRecipient(ProcessRecord app, int pid,
1382                IApplicationThread thread) {
1383            if (DEBUG_ALL) Slog.v(
1384                TAG, "New death recipient " + this
1385                + " for thread " + thread.asBinder());
1386            mApp = app;
1387            mPid = pid;
1388            mAppThread = thread;
1389        }
1390
1391        @Override
1392        public void binderDied() {
1393            if (DEBUG_ALL) Slog.v(
1394                TAG, "Death received in " + this
1395                + " for thread " + mAppThread.asBinder());
1396            synchronized(ActivityManagerService.this) {
1397                appDiedLocked(mApp, mPid, mAppThread, true);
1398            }
1399        }
1400    }
1401
1402    static final int SHOW_ERROR_UI_MSG = 1;
1403    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1404    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1405    static final int UPDATE_CONFIGURATION_MSG = 4;
1406    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1407    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1408    static final int SERVICE_TIMEOUT_MSG = 12;
1409    static final int UPDATE_TIME_ZONE = 13;
1410    static final int SHOW_UID_ERROR_UI_MSG = 14;
1411    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1412    static final int PROC_START_TIMEOUT_MSG = 20;
1413    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1414    static final int KILL_APPLICATION_MSG = 22;
1415    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1416    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1417    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1418    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1419    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1420    static final int CLEAR_DNS_CACHE_MSG = 28;
1421    static final int UPDATE_HTTP_PROXY_MSG = 29;
1422    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1423    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1424    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1425    static final int REPORT_MEM_USAGE_MSG = 33;
1426    static final int REPORT_USER_SWITCH_MSG = 34;
1427    static final int CONTINUE_USER_SWITCH_MSG = 35;
1428    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1429    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1430    static final int PERSIST_URI_GRANTS_MSG = 38;
1431    static final int REQUEST_ALL_PSS_MSG = 39;
1432    static final int START_PROFILES_MSG = 40;
1433    static final int UPDATE_TIME = 41;
1434    static final int SYSTEM_USER_START_MSG = 42;
1435    static final int SYSTEM_USER_CURRENT_MSG = 43;
1436    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1437    static final int FINISH_BOOTING_MSG = 45;
1438    static final int START_USER_SWITCH_UI_MSG = 46;
1439    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1440    static final int DISMISS_DIALOG_UI_MSG = 48;
1441    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1442    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1443    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1444    static final int DELETE_DUMPHEAP_MSG = 52;
1445    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1446    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1447    static final int REPORT_TIME_TRACKER_MSG = 55;
1448    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1449    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1450    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1451    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1452    static final int IDLE_UIDS_MSG = 60;
1453    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1454    static final int LOG_STACK_STATE = 62;
1455    static final int VR_MODE_CHANGE_MSG = 63;
1456    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1457    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1458    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1459
1460    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1461    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1462    static final int FIRST_COMPAT_MODE_MSG = 300;
1463    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1464
1465    CompatModeDialog mCompatModeDialog;
1466    long mLastMemUsageReportTime = 0;
1467
1468    /**
1469     * Flag whether the current user is a "monkey", i.e. whether
1470     * the UI is driven by a UI automation tool.
1471     */
1472    private boolean mUserIsMonkey;
1473
1474    /** Flag whether the device has a Recents UI */
1475    boolean mHasRecents;
1476
1477    /** The dimensions of the thumbnails in the Recents UI. */
1478    int mThumbnailWidth;
1479    int mThumbnailHeight;
1480
1481    final ServiceThread mHandlerThread;
1482    final MainHandler mHandler;
1483    final UiHandler mUiHandler;
1484    final ProcessStartLogger mProcessStartLogger;
1485
1486    PackageManagerInternal mPackageManagerInt;
1487
1488    final class UiHandler extends Handler {
1489        public UiHandler() {
1490            super(com.android.server.UiThread.get().getLooper(), null, true);
1491        }
1492
1493        @Override
1494        public void handleMessage(Message msg) {
1495            switch (msg.what) {
1496            case SHOW_ERROR_UI_MSG: {
1497                mAppErrors.handleShowAppErrorUi(msg);
1498                ensureBootCompleted();
1499            } break;
1500            case SHOW_NOT_RESPONDING_UI_MSG: {
1501                mAppErrors.handleShowAnrUi(msg);
1502                ensureBootCompleted();
1503            } break;
1504            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1505                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1506                synchronized (ActivityManagerService.this) {
1507                    ProcessRecord proc = (ProcessRecord) data.get("app");
1508                    if (proc == null) {
1509                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1510                        break;
1511                    }
1512                    if (proc.crashDialog != null) {
1513                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1514                        return;
1515                    }
1516                    AppErrorResult res = (AppErrorResult) data.get("result");
1517                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1518                        Dialog d = new StrictModeViolationDialog(mContext,
1519                                ActivityManagerService.this, res, proc);
1520                        d.show();
1521                        proc.crashDialog = d;
1522                    } else {
1523                        // The device is asleep, so just pretend that the user
1524                        // saw a crash dialog and hit "force quit".
1525                        res.set(0);
1526                    }
1527                }
1528                ensureBootCompleted();
1529            } break;
1530            case SHOW_FACTORY_ERROR_UI_MSG: {
1531                Dialog d = new FactoryErrorDialog(
1532                    mContext, msg.getData().getCharSequence("msg"));
1533                d.show();
1534                ensureBootCompleted();
1535            } break;
1536            case WAIT_FOR_DEBUGGER_UI_MSG: {
1537                synchronized (ActivityManagerService.this) {
1538                    ProcessRecord app = (ProcessRecord)msg.obj;
1539                    if (msg.arg1 != 0) {
1540                        if (!app.waitedForDebugger) {
1541                            Dialog d = new AppWaitingForDebuggerDialog(
1542                                    ActivityManagerService.this,
1543                                    mContext, app);
1544                            app.waitDialog = d;
1545                            app.waitedForDebugger = true;
1546                            d.show();
1547                        }
1548                    } else {
1549                        if (app.waitDialog != null) {
1550                            app.waitDialog.dismiss();
1551                            app.waitDialog = null;
1552                        }
1553                    }
1554                }
1555            } break;
1556            case SHOW_UID_ERROR_UI_MSG: {
1557                if (mShowDialogs) {
1558                    AlertDialog d = new BaseErrorDialog(mContext);
1559                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1560                    d.setCancelable(false);
1561                    d.setTitle(mContext.getText(R.string.android_system_label));
1562                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1563                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1564                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1565                    d.show();
1566                }
1567            } break;
1568            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1569                if (mShowDialogs) {
1570                    AlertDialog d = new BaseErrorDialog(mContext);
1571                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1572                    d.setCancelable(false);
1573                    d.setTitle(mContext.getText(R.string.android_system_label));
1574                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1575                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1576                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1577                    d.show();
1578                }
1579            } break;
1580            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1581                synchronized (ActivityManagerService.this) {
1582                    ActivityRecord ar = (ActivityRecord) msg.obj;
1583                    if (mCompatModeDialog != null) {
1584                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1585                                ar.info.applicationInfo.packageName)) {
1586                            return;
1587                        }
1588                        mCompatModeDialog.dismiss();
1589                        mCompatModeDialog = null;
1590                    }
1591                    if (ar != null && false) {
1592                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1593                                ar.packageName)) {
1594                            int mode = mCompatModePackages.computeCompatModeLocked(
1595                                    ar.info.applicationInfo);
1596                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1597                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1598                                mCompatModeDialog = new CompatModeDialog(
1599                                        ActivityManagerService.this, mContext,
1600                                        ar.info.applicationInfo);
1601                                mCompatModeDialog.show();
1602                            }
1603                        }
1604                    }
1605                }
1606                break;
1607            }
1608            case START_USER_SWITCH_UI_MSG: {
1609                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1610                break;
1611            }
1612            case DISMISS_DIALOG_UI_MSG: {
1613                final Dialog d = (Dialog) msg.obj;
1614                d.dismiss();
1615                break;
1616            }
1617            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1618                dispatchProcessesChanged();
1619                break;
1620            }
1621            case DISPATCH_PROCESS_DIED_UI_MSG: {
1622                final int pid = msg.arg1;
1623                final int uid = msg.arg2;
1624                dispatchProcessDied(pid, uid);
1625                break;
1626            }
1627            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1628                dispatchUidsChanged();
1629            } break;
1630            }
1631        }
1632    }
1633
1634    final class MainHandler extends Handler {
1635        public MainHandler(Looper looper) {
1636            super(looper, null, true);
1637        }
1638
1639        @Override
1640        public void handleMessage(Message msg) {
1641            switch (msg.what) {
1642            case UPDATE_CONFIGURATION_MSG: {
1643                final ContentResolver resolver = mContext.getContentResolver();
1644                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1645                        msg.arg1);
1646            } break;
1647            case GC_BACKGROUND_PROCESSES_MSG: {
1648                synchronized (ActivityManagerService.this) {
1649                    performAppGcsIfAppropriateLocked();
1650                }
1651            } break;
1652            case SERVICE_TIMEOUT_MSG: {
1653                if (mDidDexOpt) {
1654                    mDidDexOpt = false;
1655                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1656                    nmsg.obj = msg.obj;
1657                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1658                    return;
1659                }
1660                mServices.serviceTimeout((ProcessRecord)msg.obj);
1661            } break;
1662            case UPDATE_TIME_ZONE: {
1663                synchronized (ActivityManagerService.this) {
1664                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1665                        ProcessRecord r = mLruProcesses.get(i);
1666                        if (r.thread != null) {
1667                            try {
1668                                r.thread.updateTimeZone();
1669                            } catch (RemoteException ex) {
1670                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1671                            }
1672                        }
1673                    }
1674                }
1675            } break;
1676            case CLEAR_DNS_CACHE_MSG: {
1677                synchronized (ActivityManagerService.this) {
1678                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1679                        ProcessRecord r = mLruProcesses.get(i);
1680                        if (r.thread != null) {
1681                            try {
1682                                r.thread.clearDnsCache();
1683                            } catch (RemoteException ex) {
1684                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1685                            }
1686                        }
1687                    }
1688                }
1689            } break;
1690            case UPDATE_HTTP_PROXY_MSG: {
1691                ProxyInfo proxy = (ProxyInfo)msg.obj;
1692                String host = "";
1693                String port = "";
1694                String exclList = "";
1695                Uri pacFileUrl = Uri.EMPTY;
1696                if (proxy != null) {
1697                    host = proxy.getHost();
1698                    port = Integer.toString(proxy.getPort());
1699                    exclList = proxy.getExclusionListAsString();
1700                    pacFileUrl = proxy.getPacFileUrl();
1701                }
1702                synchronized (ActivityManagerService.this) {
1703                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1704                        ProcessRecord r = mLruProcesses.get(i);
1705                        if (r.thread != null) {
1706                            try {
1707                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1708                            } catch (RemoteException ex) {
1709                                Slog.w(TAG, "Failed to update http proxy for: " +
1710                                        r.info.processName);
1711                            }
1712                        }
1713                    }
1714                }
1715            } break;
1716            case PROC_START_TIMEOUT_MSG: {
1717                if (mDidDexOpt) {
1718                    mDidDexOpt = false;
1719                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1720                    nmsg.obj = msg.obj;
1721                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1722                    return;
1723                }
1724                ProcessRecord app = (ProcessRecord)msg.obj;
1725                synchronized (ActivityManagerService.this) {
1726                    processStartTimedOutLocked(app);
1727                }
1728            } break;
1729            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1730                ProcessRecord app = (ProcessRecord)msg.obj;
1731                synchronized (ActivityManagerService.this) {
1732                    processContentProviderPublishTimedOutLocked(app);
1733                }
1734            } break;
1735            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1736                synchronized (ActivityManagerService.this) {
1737                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1738                }
1739            } break;
1740            case KILL_APPLICATION_MSG: {
1741                synchronized (ActivityManagerService.this) {
1742                    int appid = msg.arg1;
1743                    boolean restart = (msg.arg2 == 1);
1744                    Bundle bundle = (Bundle)msg.obj;
1745                    String pkg = bundle.getString("pkg");
1746                    String reason = bundle.getString("reason");
1747                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1748                            false, UserHandle.USER_ALL, reason);
1749                }
1750            } break;
1751            case FINALIZE_PENDING_INTENT_MSG: {
1752                ((PendingIntentRecord)msg.obj).completeFinalize();
1753            } break;
1754            case POST_HEAVY_NOTIFICATION_MSG: {
1755                INotificationManager inm = NotificationManager.getService();
1756                if (inm == null) {
1757                    return;
1758                }
1759
1760                ActivityRecord root = (ActivityRecord)msg.obj;
1761                ProcessRecord process = root.app;
1762                if (process == null) {
1763                    return;
1764                }
1765
1766                try {
1767                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1768                    String text = mContext.getString(R.string.heavy_weight_notification,
1769                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1770                    Notification notification = new Notification.Builder(context)
1771                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1772                            .setWhen(0)
1773                            .setOngoing(true)
1774                            .setTicker(text)
1775                            .setColor(mContext.getColor(
1776                                    com.android.internal.R.color.system_notification_accent_color))
1777                            .setContentTitle(text)
1778                            .setContentText(
1779                                    mContext.getText(R.string.heavy_weight_notification_detail))
1780                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1781                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1782                                    new UserHandle(root.userId)))
1783                            .build();
1784                    try {
1785                        int[] outId = new int[1];
1786                        inm.enqueueNotificationWithTag("android", "android", null,
1787                                R.string.heavy_weight_notification,
1788                                notification, outId, root.userId);
1789                    } catch (RuntimeException e) {
1790                        Slog.w(ActivityManagerService.TAG,
1791                                "Error showing notification for heavy-weight app", e);
1792                    } catch (RemoteException e) {
1793                    }
1794                } catch (NameNotFoundException e) {
1795                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1796                }
1797            } break;
1798            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1799                INotificationManager inm = NotificationManager.getService();
1800                if (inm == null) {
1801                    return;
1802                }
1803                try {
1804                    inm.cancelNotificationWithTag("android", null,
1805                            R.string.heavy_weight_notification,  msg.arg1);
1806                } catch (RuntimeException e) {
1807                    Slog.w(ActivityManagerService.TAG,
1808                            "Error canceling notification for service", e);
1809                } catch (RemoteException e) {
1810                }
1811            } break;
1812            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1813                synchronized (ActivityManagerService.this) {
1814                    checkExcessivePowerUsageLocked(true);
1815                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1816                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1817                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1818                }
1819            } break;
1820            case REPORT_MEM_USAGE_MSG: {
1821                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1822                Thread thread = new Thread() {
1823                    @Override public void run() {
1824                        reportMemUsage(memInfos);
1825                    }
1826                };
1827                thread.start();
1828                break;
1829            }
1830            case REPORT_USER_SWITCH_MSG: {
1831                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1832                break;
1833            }
1834            case CONTINUE_USER_SWITCH_MSG: {
1835                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1836                break;
1837            }
1838            case USER_SWITCH_TIMEOUT_MSG: {
1839                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1840                break;
1841            }
1842            case IMMERSIVE_MODE_LOCK_MSG: {
1843                final boolean nextState = (msg.arg1 != 0);
1844                if (mUpdateLock.isHeld() != nextState) {
1845                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1846                            "Applying new update lock state '" + nextState
1847                            + "' for " + (ActivityRecord)msg.obj);
1848                    if (nextState) {
1849                        mUpdateLock.acquire();
1850                    } else {
1851                        mUpdateLock.release();
1852                    }
1853                }
1854                break;
1855            }
1856            case PERSIST_URI_GRANTS_MSG: {
1857                writeGrantedUriPermissions();
1858                break;
1859            }
1860            case REQUEST_ALL_PSS_MSG: {
1861                synchronized (ActivityManagerService.this) {
1862                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1863                }
1864                break;
1865            }
1866            case START_PROFILES_MSG: {
1867                synchronized (ActivityManagerService.this) {
1868                    mUserController.startProfilesLocked();
1869                }
1870                break;
1871            }
1872            case UPDATE_TIME: {
1873                synchronized (ActivityManagerService.this) {
1874                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1875                        ProcessRecord r = mLruProcesses.get(i);
1876                        if (r.thread != null) {
1877                            try {
1878                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1879                            } catch (RemoteException ex) {
1880                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1881                            }
1882                        }
1883                    }
1884                }
1885                break;
1886            }
1887            case SYSTEM_USER_START_MSG: {
1888                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1889                        Integer.toString(msg.arg1), msg.arg1);
1890                mSystemServiceManager.startUser(msg.arg1);
1891                break;
1892            }
1893            case SYSTEM_USER_UNLOCK_MSG: {
1894                final int userId = msg.arg1;
1895                mSystemServiceManager.unlockUser(userId);
1896                mRecentTasks.loadUserRecentsLocked(userId);
1897                installEncryptionUnawareProviders(userId);
1898                break;
1899            }
1900            case SYSTEM_USER_CURRENT_MSG: {
1901                mBatteryStatsService.noteEvent(
1902                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1903                        Integer.toString(msg.arg2), msg.arg2);
1904                mBatteryStatsService.noteEvent(
1905                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1906                        Integer.toString(msg.arg1), msg.arg1);
1907                mSystemServiceManager.switchUser(msg.arg1);
1908                break;
1909            }
1910            case ENTER_ANIMATION_COMPLETE_MSG: {
1911                synchronized (ActivityManagerService.this) {
1912                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1913                    if (r != null && r.app != null && r.app.thread != null) {
1914                        try {
1915                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1916                        } catch (RemoteException e) {
1917                        }
1918                    }
1919                }
1920                break;
1921            }
1922            case FINISH_BOOTING_MSG: {
1923                if (msg.arg1 != 0) {
1924                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1925                    finishBooting();
1926                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1927                }
1928                if (msg.arg2 != 0) {
1929                    enableScreenAfterBoot();
1930                }
1931                break;
1932            }
1933            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1934                try {
1935                    Locale l = (Locale) msg.obj;
1936                    IBinder service = ServiceManager.getService("mount");
1937                    IMountService mountService = IMountService.Stub.asInterface(service);
1938                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1939                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1940                } catch (RemoteException e) {
1941                    Log.e(TAG, "Error storing locale for decryption UI", e);
1942                }
1943                break;
1944            }
1945            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1946                synchronized (ActivityManagerService.this) {
1947                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1948                        try {
1949                            // Make a one-way callback to the listener
1950                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1951                        } catch (RemoteException e){
1952                            // Handled by the RemoteCallbackList
1953                        }
1954                    }
1955                    mTaskStackListeners.finishBroadcast();
1956                }
1957                break;
1958            }
1959            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
1960                synchronized (ActivityManagerService.this) {
1961                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1962                        try {
1963                            // Make a one-way callback to the listener
1964                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
1965                        } catch (RemoteException e){
1966                            // Handled by the RemoteCallbackList
1967                        }
1968                    }
1969                    mTaskStackListeners.finishBroadcast();
1970                }
1971                break;
1972            }
1973            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
1974                synchronized (ActivityManagerService.this) {
1975                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1976                        try {
1977                            // Make a one-way callback to the listener
1978                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
1979                        } catch (RemoteException e){
1980                            // Handled by the RemoteCallbackList
1981                        }
1982                    }
1983                    mTaskStackListeners.finishBroadcast();
1984                }
1985                break;
1986            }
1987            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
1988                synchronized (ActivityManagerService.this) {
1989                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1990                        try {
1991                            // Make a one-way callback to the listener
1992                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
1993                        } catch (RemoteException e){
1994                            // Handled by the RemoteCallbackList
1995                        }
1996                    }
1997                    mTaskStackListeners.finishBroadcast();
1998                }
1999                break;
2000            }
2001            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2002                final int uid = msg.arg1;
2003                final byte[] firstPacket = (byte[]) msg.obj;
2004
2005                synchronized (mPidsSelfLocked) {
2006                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2007                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2008                        if (p.uid == uid) {
2009                            try {
2010                                p.thread.notifyCleartextNetwork(firstPacket);
2011                            } catch (RemoteException ignored) {
2012                            }
2013                        }
2014                    }
2015                }
2016                break;
2017            }
2018            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2019                final String procName;
2020                final int uid;
2021                final long memLimit;
2022                final String reportPackage;
2023                synchronized (ActivityManagerService.this) {
2024                    procName = mMemWatchDumpProcName;
2025                    uid = mMemWatchDumpUid;
2026                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2027                    if (val == null) {
2028                        val = mMemWatchProcesses.get(procName, 0);
2029                    }
2030                    if (val != null) {
2031                        memLimit = val.first;
2032                        reportPackage = val.second;
2033                    } else {
2034                        memLimit = 0;
2035                        reportPackage = null;
2036                    }
2037                }
2038                if (procName == null) {
2039                    return;
2040                }
2041
2042                if (DEBUG_PSS) Slog.d(TAG_PSS,
2043                        "Showing dump heap notification from " + procName + "/" + uid);
2044
2045                INotificationManager inm = NotificationManager.getService();
2046                if (inm == null) {
2047                    return;
2048                }
2049
2050                String text = mContext.getString(R.string.dump_heap_notification, procName);
2051
2052
2053                Intent deleteIntent = new Intent();
2054                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2055                Intent intent = new Intent();
2056                intent.setClassName("android", DumpHeapActivity.class.getName());
2057                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2058                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2059                if (reportPackage != null) {
2060                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2061                }
2062                int userId = UserHandle.getUserId(uid);
2063                Notification notification = new Notification.Builder(mContext)
2064                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2065                        .setWhen(0)
2066                        .setOngoing(true)
2067                        .setAutoCancel(true)
2068                        .setTicker(text)
2069                        .setColor(mContext.getColor(
2070                                com.android.internal.R.color.system_notification_accent_color))
2071                        .setContentTitle(text)
2072                        .setContentText(
2073                                mContext.getText(R.string.dump_heap_notification_detail))
2074                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2075                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2076                                new UserHandle(userId)))
2077                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2078                                deleteIntent, 0, UserHandle.SYSTEM))
2079                        .build();
2080
2081                try {
2082                    int[] outId = new int[1];
2083                    inm.enqueueNotificationWithTag("android", "android", null,
2084                            R.string.dump_heap_notification,
2085                            notification, outId, userId);
2086                } catch (RuntimeException e) {
2087                    Slog.w(ActivityManagerService.TAG,
2088                            "Error showing notification for dump heap", e);
2089                } catch (RemoteException e) {
2090                }
2091            } break;
2092            case DELETE_DUMPHEAP_MSG: {
2093                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2094                        DumpHeapActivity.JAVA_URI,
2095                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2096                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2097                        UserHandle.myUserId());
2098                synchronized (ActivityManagerService.this) {
2099                    mMemWatchDumpFile = null;
2100                    mMemWatchDumpProcName = null;
2101                    mMemWatchDumpPid = -1;
2102                    mMemWatchDumpUid = -1;
2103                }
2104            } break;
2105            case FOREGROUND_PROFILE_CHANGED_MSG: {
2106                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2107            } break;
2108            case REPORT_TIME_TRACKER_MSG: {
2109                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2110                tracker.deliverResult(mContext);
2111            } break;
2112            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2113                mUserController.dispatchUserSwitchComplete(msg.arg1);
2114            } break;
2115            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2116                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2117                try {
2118                    connection.shutdown();
2119                } catch (RemoteException e) {
2120                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2121                }
2122                // Only a UiAutomation can set this flag and now that
2123                // it is finished we make sure it is reset to its default.
2124                mUserIsMonkey = false;
2125            } break;
2126            case APP_BOOST_DEACTIVATE_MSG: {
2127                synchronized(ActivityManagerService.this) {
2128                    if (mIsBoosted) {
2129                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2130                            nativeMigrateFromBoost();
2131                            mIsBoosted = false;
2132                            mBoostStartTime = 0;
2133                        } else {
2134                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2135                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2136                        }
2137                    }
2138                }
2139            } break;
2140            case IDLE_UIDS_MSG: {
2141                idleUids();
2142            } break;
2143            case LOG_STACK_STATE: {
2144                synchronized (ActivityManagerService.this) {
2145                    mStackSupervisor.logStackState();
2146                }
2147            } break;
2148            case VR_MODE_CHANGE_MSG: {
2149                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2150                final boolean vrMode = msg.arg1 != 0;
2151                vrService.setVrMode(vrMode);
2152
2153                if (mInVrMode != vrMode) {
2154                    synchronized (ActivityManagerService.this) {
2155                        mInVrMode = vrMode;
2156                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2157                    }
2158                }
2159            } break;
2160            }
2161        }
2162    };
2163
2164    static final int COLLECT_PSS_BG_MSG = 1;
2165
2166    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2167        @Override
2168        public void handleMessage(Message msg) {
2169            switch (msg.what) {
2170            case COLLECT_PSS_BG_MSG: {
2171                long start = SystemClock.uptimeMillis();
2172                MemInfoReader memInfo = null;
2173                synchronized (ActivityManagerService.this) {
2174                    if (mFullPssPending) {
2175                        mFullPssPending = false;
2176                        memInfo = new MemInfoReader();
2177                    }
2178                }
2179                if (memInfo != null) {
2180                    updateCpuStatsNow();
2181                    long nativeTotalPss = 0;
2182                    synchronized (mProcessCpuTracker) {
2183                        final int N = mProcessCpuTracker.countStats();
2184                        for (int j=0; j<N; j++) {
2185                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2186                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2187                                // This is definitely an application process; skip it.
2188                                continue;
2189                            }
2190                            synchronized (mPidsSelfLocked) {
2191                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2192                                    // This is one of our own processes; skip it.
2193                                    continue;
2194                                }
2195                            }
2196                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2197                        }
2198                    }
2199                    memInfo.readMemInfo();
2200                    synchronized (ActivityManagerService.this) {
2201                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2202                                + (SystemClock.uptimeMillis()-start) + "ms");
2203                        final long cachedKb = memInfo.getCachedSizeKb();
2204                        final long freeKb = memInfo.getFreeSizeKb();
2205                        final long zramKb = memInfo.getZramTotalSizeKb();
2206                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2207                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2208                                kernelKb*1024, nativeTotalPss*1024);
2209                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2210                                nativeTotalPss);
2211                    }
2212                }
2213
2214                int num = 0;
2215                long[] tmp = new long[2];
2216                do {
2217                    ProcessRecord proc;
2218                    int procState;
2219                    int pid;
2220                    long lastPssTime;
2221                    synchronized (ActivityManagerService.this) {
2222                        if (mPendingPssProcesses.size() <= 0) {
2223                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2224                                    "Collected PSS of " + num + " processes in "
2225                                    + (SystemClock.uptimeMillis() - start) + "ms");
2226                            mPendingPssProcesses.clear();
2227                            return;
2228                        }
2229                        proc = mPendingPssProcesses.remove(0);
2230                        procState = proc.pssProcState;
2231                        lastPssTime = proc.lastPssTime;
2232                        if (proc.thread != null && procState == proc.setProcState
2233                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2234                                        < SystemClock.uptimeMillis()) {
2235                            pid = proc.pid;
2236                        } else {
2237                            proc = null;
2238                            pid = 0;
2239                        }
2240                    }
2241                    if (proc != null) {
2242                        long pss = Debug.getPss(pid, tmp, null);
2243                        synchronized (ActivityManagerService.this) {
2244                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2245                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2246                                num++;
2247                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2248                                        SystemClock.uptimeMillis());
2249                            }
2250                        }
2251                    }
2252                } while (true);
2253            }
2254            }
2255        }
2256    };
2257
2258    public void setSystemProcess() {
2259        try {
2260            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2261            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2262            ServiceManager.addService("meminfo", new MemBinder(this));
2263            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2264            ServiceManager.addService("dbinfo", new DbBinder(this));
2265            if (MONITOR_CPU_USAGE) {
2266                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2267            }
2268            ServiceManager.addService("permission", new PermissionController(this));
2269            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2270
2271            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2272                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2273            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2274
2275            synchronized (this) {
2276                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2277                app.persistent = true;
2278                app.pid = MY_PID;
2279                app.maxAdj = ProcessList.SYSTEM_ADJ;
2280                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2281                synchronized (mPidsSelfLocked) {
2282                    mPidsSelfLocked.put(app.pid, app);
2283                }
2284                updateLruProcessLocked(app, false, null);
2285                updateOomAdjLocked();
2286            }
2287        } catch (PackageManager.NameNotFoundException e) {
2288            throw new RuntimeException(
2289                    "Unable to find android system package", e);
2290        }
2291    }
2292
2293    public void setWindowManager(WindowManagerService wm) {
2294        mWindowManager = wm;
2295        mStackSupervisor.setWindowManager(wm);
2296        mActivityStarter.setWindowManager(wm);
2297    }
2298
2299    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2300        mUsageStatsService = usageStatsManager;
2301    }
2302
2303    public void startObservingNativeCrashes() {
2304        final NativeCrashListener ncl = new NativeCrashListener(this);
2305        ncl.start();
2306    }
2307
2308    public IAppOpsService getAppOpsService() {
2309        return mAppOpsService;
2310    }
2311
2312    static class MemBinder extends Binder {
2313        ActivityManagerService mActivityManagerService;
2314        MemBinder(ActivityManagerService activityManagerService) {
2315            mActivityManagerService = activityManagerService;
2316        }
2317
2318        @Override
2319        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2320            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2321                    != PackageManager.PERMISSION_GRANTED) {
2322                pw.println("Permission Denial: can't dump meminfo from from pid="
2323                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2324                        + " without permission " + android.Manifest.permission.DUMP);
2325                return;
2326            }
2327
2328            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2329        }
2330    }
2331
2332    static class GraphicsBinder extends Binder {
2333        ActivityManagerService mActivityManagerService;
2334        GraphicsBinder(ActivityManagerService activityManagerService) {
2335            mActivityManagerService = activityManagerService;
2336        }
2337
2338        @Override
2339        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2340            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2341                    != PackageManager.PERMISSION_GRANTED) {
2342                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2343                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2344                        + " without permission " + android.Manifest.permission.DUMP);
2345                return;
2346            }
2347
2348            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2349        }
2350    }
2351
2352    static class DbBinder extends Binder {
2353        ActivityManagerService mActivityManagerService;
2354        DbBinder(ActivityManagerService activityManagerService) {
2355            mActivityManagerService = activityManagerService;
2356        }
2357
2358        @Override
2359        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2360            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2361                    != PackageManager.PERMISSION_GRANTED) {
2362                pw.println("Permission Denial: can't dump dbinfo from from pid="
2363                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2364                        + " without permission " + android.Manifest.permission.DUMP);
2365                return;
2366            }
2367
2368            mActivityManagerService.dumpDbInfo(fd, pw, args);
2369        }
2370    }
2371
2372    static class CpuBinder extends Binder {
2373        ActivityManagerService mActivityManagerService;
2374        CpuBinder(ActivityManagerService activityManagerService) {
2375            mActivityManagerService = activityManagerService;
2376        }
2377
2378        @Override
2379        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2380            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2381                    != PackageManager.PERMISSION_GRANTED) {
2382                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2383                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2384                        + " without permission " + android.Manifest.permission.DUMP);
2385                return;
2386            }
2387
2388            synchronized (mActivityManagerService.mProcessCpuTracker) {
2389                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2390                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2391                        SystemClock.uptimeMillis()));
2392            }
2393        }
2394    }
2395
2396    public static final class Lifecycle extends SystemService {
2397        private final ActivityManagerService mService;
2398
2399        public Lifecycle(Context context) {
2400            super(context);
2401            mService = new ActivityManagerService(context);
2402        }
2403
2404        @Override
2405        public void onStart() {
2406            mService.start();
2407        }
2408
2409        public ActivityManagerService getService() {
2410            return mService;
2411        }
2412    }
2413
2414    // Note: This method is invoked on the main thread but may need to attach various
2415    // handlers to other threads.  So take care to be explicit about the looper.
2416    public ActivityManagerService(Context systemContext) {
2417        mContext = systemContext;
2418        mFactoryTest = FactoryTest.getMode();
2419        mSystemThread = ActivityThread.currentActivityThread();
2420
2421        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2422
2423        mHandlerThread = new ServiceThread(TAG,
2424                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2425        mHandlerThread.start();
2426        mHandler = new MainHandler(mHandlerThread.getLooper());
2427        mUiHandler = new UiHandler();
2428
2429        mProcessStartLogger = new ProcessStartLogger();
2430
2431        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2432                "foreground", BROADCAST_FG_TIMEOUT, false);
2433        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2434                "background", BROADCAST_BG_TIMEOUT, true);
2435        mBroadcastQueues[0] = mFgBroadcastQueue;
2436        mBroadcastQueues[1] = mBgBroadcastQueue;
2437
2438        mServices = new ActiveServices(this);
2439        mProviderMap = new ProviderMap(this);
2440        mAppErrors = new AppErrors(mContext, this);
2441
2442        // TODO: Move creation of battery stats service outside of activity manager service.
2443        File dataDir = Environment.getDataDirectory();
2444        File systemDir = new File(dataDir, "system");
2445        systemDir.mkdirs();
2446        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2447        mBatteryStatsService.getActiveStatistics().readLocked();
2448        mBatteryStatsService.scheduleWriteToDisk();
2449        mOnBattery = DEBUG_POWER ? true
2450                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2451        mBatteryStatsService.getActiveStatistics().setCallback(this);
2452
2453        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2454
2455        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2456        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2457                new IAppOpsCallback.Stub() {
2458                    @Override public void opChanged(int op, int uid, String packageName) {
2459                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2460                            if (mAppOpsService.checkOperation(op, uid, packageName)
2461                                    != AppOpsManager.MODE_ALLOWED) {
2462                                runInBackgroundDisabled(uid);
2463                            }
2464                        }
2465                    }
2466                });
2467
2468        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2469
2470        mUserController = new UserController(this);
2471
2472        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2473            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2474
2475        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2476
2477        mConfiguration.setToDefaults();
2478        mConfiguration.setLocales(LocaleList.getDefault());
2479
2480        mConfigurationSeq = mConfiguration.seq = 1;
2481        mProcessCpuTracker.init();
2482
2483        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2484        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2485        mStackSupervisor = new ActivityStackSupervisor(this);
2486        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2487        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2488
2489        mProcessCpuThread = new Thread("CpuTracker") {
2490            @Override
2491            public void run() {
2492                while (true) {
2493                    try {
2494                        try {
2495                            synchronized(this) {
2496                                final long now = SystemClock.uptimeMillis();
2497                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2498                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2499                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2500                                //        + ", write delay=" + nextWriteDelay);
2501                                if (nextWriteDelay < nextCpuDelay) {
2502                                    nextCpuDelay = nextWriteDelay;
2503                                }
2504                                if (nextCpuDelay > 0) {
2505                                    mProcessCpuMutexFree.set(true);
2506                                    this.wait(nextCpuDelay);
2507                                }
2508                            }
2509                        } catch (InterruptedException e) {
2510                        }
2511                        updateCpuStatsNow();
2512                    } catch (Exception e) {
2513                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2514                    }
2515                }
2516            }
2517        };
2518
2519        Watchdog.getInstance().addMonitor(this);
2520        Watchdog.getInstance().addThread(mHandler);
2521    }
2522
2523    public void setSystemServiceManager(SystemServiceManager mgr) {
2524        mSystemServiceManager = mgr;
2525    }
2526
2527    public void setInstaller(Installer installer) {
2528        mInstaller = installer;
2529    }
2530
2531    private void start() {
2532        Process.removeAllProcessGroups();
2533        mProcessCpuThread.start();
2534
2535        mBatteryStatsService.publish(mContext);
2536        mAppOpsService.publish(mContext);
2537        Slog.d("AppOps", "AppOpsService published");
2538        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2539    }
2540
2541    void onUserStoppedLocked(int userId) {
2542        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2543    }
2544
2545    public void initPowerManagement() {
2546        mStackSupervisor.initPowerManagement();
2547        mBatteryStatsService.initPowerManagement();
2548        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2549        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2550        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2551        mVoiceWakeLock.setReferenceCounted(false);
2552    }
2553
2554    @Override
2555    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2556            throws RemoteException {
2557        if (code == SYSPROPS_TRANSACTION) {
2558            // We need to tell all apps about the system property change.
2559            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2560            synchronized(this) {
2561                final int NP = mProcessNames.getMap().size();
2562                for (int ip=0; ip<NP; ip++) {
2563                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2564                    final int NA = apps.size();
2565                    for (int ia=0; ia<NA; ia++) {
2566                        ProcessRecord app = apps.valueAt(ia);
2567                        if (app.thread != null) {
2568                            procs.add(app.thread.asBinder());
2569                        }
2570                    }
2571                }
2572            }
2573
2574            int N = procs.size();
2575            for (int i=0; i<N; i++) {
2576                Parcel data2 = Parcel.obtain();
2577                try {
2578                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2579                } catch (RemoteException e) {
2580                }
2581                data2.recycle();
2582            }
2583        }
2584        try {
2585            return super.onTransact(code, data, reply, flags);
2586        } catch (RuntimeException e) {
2587            // The activity manager only throws security exceptions, so let's
2588            // log all others.
2589            if (!(e instanceof SecurityException)) {
2590                Slog.wtf(TAG, "Activity Manager Crash", e);
2591            }
2592            throw e;
2593        }
2594    }
2595
2596    void updateCpuStats() {
2597        final long now = SystemClock.uptimeMillis();
2598        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2599            return;
2600        }
2601        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2602            synchronized (mProcessCpuThread) {
2603                mProcessCpuThread.notify();
2604            }
2605        }
2606    }
2607
2608    void updateCpuStatsNow() {
2609        synchronized (mProcessCpuTracker) {
2610            mProcessCpuMutexFree.set(false);
2611            final long now = SystemClock.uptimeMillis();
2612            boolean haveNewCpuStats = false;
2613
2614            if (MONITOR_CPU_USAGE &&
2615                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2616                mLastCpuTime.set(now);
2617                mProcessCpuTracker.update();
2618                if (mProcessCpuTracker.hasGoodLastStats()) {
2619                    haveNewCpuStats = true;
2620                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2621                    //Slog.i(TAG, "Total CPU usage: "
2622                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2623
2624                    // Slog the cpu usage if the property is set.
2625                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2626                        int user = mProcessCpuTracker.getLastUserTime();
2627                        int system = mProcessCpuTracker.getLastSystemTime();
2628                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2629                        int irq = mProcessCpuTracker.getLastIrqTime();
2630                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2631                        int idle = mProcessCpuTracker.getLastIdleTime();
2632
2633                        int total = user + system + iowait + irq + softIrq + idle;
2634                        if (total == 0) total = 1;
2635
2636                        EventLog.writeEvent(EventLogTags.CPU,
2637                                ((user+system+iowait+irq+softIrq) * 100) / total,
2638                                (user * 100) / total,
2639                                (system * 100) / total,
2640                                (iowait * 100) / total,
2641                                (irq * 100) / total,
2642                                (softIrq * 100) / total);
2643                    }
2644                }
2645            }
2646
2647            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2648            synchronized(bstats) {
2649                synchronized(mPidsSelfLocked) {
2650                    if (haveNewCpuStats) {
2651                        if (bstats.startAddingCpuLocked()) {
2652                            int totalUTime = 0;
2653                            int totalSTime = 0;
2654                            final int N = mProcessCpuTracker.countStats();
2655                            for (int i=0; i<N; i++) {
2656                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2657                                if (!st.working) {
2658                                    continue;
2659                                }
2660                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2661                                totalUTime += st.rel_utime;
2662                                totalSTime += st.rel_stime;
2663                                if (pr != null) {
2664                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2665                                    if (ps == null || !ps.isActive()) {
2666                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2667                                                pr.info.uid, pr.processName);
2668                                    }
2669                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2670                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2671                                } else {
2672                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2673                                    if (ps == null || !ps.isActive()) {
2674                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2675                                                bstats.mapUid(st.uid), st.name);
2676                                    }
2677                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2678                                }
2679                            }
2680                            final int userTime = mProcessCpuTracker.getLastUserTime();
2681                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2682                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2683                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2684                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2685                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2686                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2687                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2688                        }
2689                    }
2690                }
2691
2692                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2693                    mLastWriteTime = now;
2694                    mBatteryStatsService.scheduleWriteToDisk();
2695                }
2696            }
2697        }
2698    }
2699
2700    @Override
2701    public void batteryNeedsCpuUpdate() {
2702        updateCpuStatsNow();
2703    }
2704
2705    @Override
2706    public void batteryPowerChanged(boolean onBattery) {
2707        // When plugging in, update the CPU stats first before changing
2708        // the plug state.
2709        updateCpuStatsNow();
2710        synchronized (this) {
2711            synchronized(mPidsSelfLocked) {
2712                mOnBattery = DEBUG_POWER ? true : onBattery;
2713            }
2714        }
2715    }
2716
2717    @Override
2718    public void batterySendBroadcast(Intent intent) {
2719        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2720                AppOpsManager.OP_NONE, null, false, false,
2721                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2722    }
2723
2724    /**
2725     * Initialize the application bind args. These are passed to each
2726     * process when the bindApplication() IPC is sent to the process. They're
2727     * lazily setup to make sure the services are running when they're asked for.
2728     */
2729    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2730        if (mAppBindArgs == null) {
2731            mAppBindArgs = new HashMap<>();
2732
2733            // Isolated processes won't get this optimization, so that we don't
2734            // violate the rules about which services they have access to.
2735            if (!isolated) {
2736                // Setup the application init args
2737                mAppBindArgs.put("package", ServiceManager.getService("package"));
2738                mAppBindArgs.put("window", ServiceManager.getService("window"));
2739                mAppBindArgs.put(Context.ALARM_SERVICE,
2740                        ServiceManager.getService(Context.ALARM_SERVICE));
2741            }
2742        }
2743        return mAppBindArgs;
2744    }
2745
2746    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2747        if (r == null || mFocusedActivity == r) {
2748            return false;
2749        }
2750
2751        if (!r.isFocusable()) {
2752            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2753            return false;
2754        }
2755
2756        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2757
2758        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2759        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2760                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2761        mDoingSetFocusedActivity = true;
2762
2763        final ActivityRecord last = mFocusedActivity;
2764        mFocusedActivity = r;
2765        if (r.task.isApplicationTask()) {
2766            if (mCurAppTimeTracker != r.appTimeTracker) {
2767                // We are switching app tracking.  Complete the current one.
2768                if (mCurAppTimeTracker != null) {
2769                    mCurAppTimeTracker.stop();
2770                    mHandler.obtainMessage(
2771                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2772                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2773                    mCurAppTimeTracker = null;
2774                }
2775                if (r.appTimeTracker != null) {
2776                    mCurAppTimeTracker = r.appTimeTracker;
2777                    startTimeTrackingFocusedActivityLocked();
2778                }
2779            } else {
2780                startTimeTrackingFocusedActivityLocked();
2781            }
2782        } else {
2783            r.appTimeTracker = null;
2784        }
2785        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2786        // TODO: Probably not, because we don't want to resume voice on switching
2787        // back to this activity
2788        if (r.task.voiceInteractor != null) {
2789            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2790        } else {
2791            finishRunningVoiceLocked();
2792            IVoiceInteractionSession session;
2793            if (last != null && ((session = last.task.voiceSession) != null
2794                    || (session = last.voiceSession) != null)) {
2795                // We had been in a voice interaction session, but now focused has
2796                // move to something different.  Just finish the session, we can't
2797                // return to it and retain the proper state and synchronization with
2798                // the voice interaction service.
2799                finishVoiceTask(session);
2800            }
2801        }
2802        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2803            mWindowManager.setFocusedApp(r.appToken, true);
2804        }
2805        applyUpdateLockStateLocked(r);
2806        applyUpdateVrModeLocked(r);
2807        if (mFocusedActivity.userId != mLastFocusedUserId) {
2808            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2809            mHandler.obtainMessage(
2810                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2811            mLastFocusedUserId = mFocusedActivity.userId;
2812        }
2813
2814        // Log a warning if the focused app is changed during the process. This could
2815        // indicate a problem of the focus setting logic!
2816        if (mFocusedActivity != r) Slog.w(TAG,
2817                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2818        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2819
2820        EventLogTags.writeAmFocusedActivity(
2821                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2822                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2823                reason);
2824        return true;
2825    }
2826
2827    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2828        if (mFocusedActivity != goingAway) {
2829            return;
2830        }
2831
2832        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2833        if (focusedStack != null) {
2834            final ActivityRecord top = focusedStack.topActivity();
2835            if (top != null && top.userId != mLastFocusedUserId) {
2836                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2837                mHandler.sendMessage(
2838                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2839                mLastFocusedUserId = top.userId;
2840            }
2841        }
2842
2843        // Try to move focus to another activity if possible.
2844        if (setFocusedActivityLocked(
2845                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2846            return;
2847        }
2848
2849        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2850                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2851        mFocusedActivity = null;
2852        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2853    }
2854
2855    @Override
2856    public void setFocusedStack(int stackId) {
2857        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2858        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2859        final long callingId = Binder.clearCallingIdentity();
2860        try {
2861            synchronized (this) {
2862                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2863                if (stack == null) {
2864                    return;
2865                }
2866                final ActivityRecord r = stack.topRunningActivityLocked();
2867                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2868                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2869                }
2870            }
2871        } finally {
2872            Binder.restoreCallingIdentity(callingId);
2873        }
2874    }
2875
2876    @Override
2877    public void setFocusedTask(int taskId) {
2878        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2879        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2880        final long callingId = Binder.clearCallingIdentity();
2881        try {
2882            synchronized (this) {
2883                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2884                if (task == null) {
2885                    return;
2886                }
2887                final ActivityRecord r = task.topRunningActivityLocked();
2888                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2889                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2890                }
2891            }
2892        } finally {
2893            Binder.restoreCallingIdentity(callingId);
2894        }
2895    }
2896
2897    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2898    @Override
2899    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2900        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2901        synchronized (this) {
2902            if (listener != null) {
2903                mTaskStackListeners.register(listener);
2904            }
2905        }
2906    }
2907
2908    @Override
2909    public void notifyActivityDrawn(IBinder token) {
2910        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2911        synchronized (this) {
2912            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2913            if (r != null) {
2914                r.task.stack.notifyActivityDrawnLocked(r);
2915            }
2916        }
2917    }
2918
2919    final void applyUpdateLockStateLocked(ActivityRecord r) {
2920        // Modifications to the UpdateLock state are done on our handler, outside
2921        // the activity manager's locks.  The new state is determined based on the
2922        // state *now* of the relevant activity record.  The object is passed to
2923        // the handler solely for logging detail, not to be consulted/modified.
2924        final boolean nextState = r != null && r.immersive;
2925        mHandler.sendMessage(
2926                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2927    }
2928
2929    final void applyUpdateVrModeLocked(ActivityRecord r) {
2930        mHandler.sendMessage(
2931                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2932    }
2933
2934    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2935        Message msg = Message.obtain();
2936        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2937        msg.obj = r.task.askedCompatMode ? null : r;
2938        mUiHandler.sendMessage(msg);
2939    }
2940
2941    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2942            String what, Object obj, ProcessRecord srcApp) {
2943        app.lastActivityTime = now;
2944
2945        if (app.activities.size() > 0) {
2946            // Don't want to touch dependent processes that are hosting activities.
2947            return index;
2948        }
2949
2950        int lrui = mLruProcesses.lastIndexOf(app);
2951        if (lrui < 0) {
2952            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2953                    + what + " " + obj + " from " + srcApp);
2954            return index;
2955        }
2956
2957        if (lrui >= index) {
2958            // Don't want to cause this to move dependent processes *back* in the
2959            // list as if they were less frequently used.
2960            return index;
2961        }
2962
2963        if (lrui >= mLruProcessActivityStart) {
2964            // Don't want to touch dependent processes that are hosting activities.
2965            return index;
2966        }
2967
2968        mLruProcesses.remove(lrui);
2969        if (index > 0) {
2970            index--;
2971        }
2972        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2973                + " in LRU list: " + app);
2974        mLruProcesses.add(index, app);
2975        return index;
2976    }
2977
2978    static void killProcessGroup(int uid, int pid) {
2979        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2980        Process.killProcessGroup(uid, pid);
2981        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2982    }
2983
2984    final void removeLruProcessLocked(ProcessRecord app) {
2985        int lrui = mLruProcesses.lastIndexOf(app);
2986        if (lrui >= 0) {
2987            if (!app.killed) {
2988                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2989                Process.killProcessQuiet(app.pid);
2990                killProcessGroup(app.info.uid, app.pid);
2991            }
2992            if (lrui <= mLruProcessActivityStart) {
2993                mLruProcessActivityStart--;
2994            }
2995            if (lrui <= mLruProcessServiceStart) {
2996                mLruProcessServiceStart--;
2997            }
2998            mLruProcesses.remove(lrui);
2999        }
3000    }
3001
3002    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3003            ProcessRecord client) {
3004        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3005                || app.treatLikeActivity;
3006        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3007        if (!activityChange && hasActivity) {
3008            // The process has activities, so we are only allowing activity-based adjustments
3009            // to move it.  It should be kept in the front of the list with other
3010            // processes that have activities, and we don't want those to change their
3011            // order except due to activity operations.
3012            return;
3013        }
3014
3015        mLruSeq++;
3016        final long now = SystemClock.uptimeMillis();
3017        app.lastActivityTime = now;
3018
3019        // First a quick reject: if the app is already at the position we will
3020        // put it, then there is nothing to do.
3021        if (hasActivity) {
3022            final int N = mLruProcesses.size();
3023            if (N > 0 && mLruProcesses.get(N-1) == app) {
3024                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3025                return;
3026            }
3027        } else {
3028            if (mLruProcessServiceStart > 0
3029                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3030                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3031                return;
3032            }
3033        }
3034
3035        int lrui = mLruProcesses.lastIndexOf(app);
3036
3037        if (app.persistent && lrui >= 0) {
3038            // We don't care about the position of persistent processes, as long as
3039            // they are in the list.
3040            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3041            return;
3042        }
3043
3044        /* In progress: compute new position first, so we can avoid doing work
3045           if the process is not actually going to move.  Not yet working.
3046        int addIndex;
3047        int nextIndex;
3048        boolean inActivity = false, inService = false;
3049        if (hasActivity) {
3050            // Process has activities, put it at the very tipsy-top.
3051            addIndex = mLruProcesses.size();
3052            nextIndex = mLruProcessServiceStart;
3053            inActivity = true;
3054        } else if (hasService) {
3055            // Process has services, put it at the top of the service list.
3056            addIndex = mLruProcessActivityStart;
3057            nextIndex = mLruProcessServiceStart;
3058            inActivity = true;
3059            inService = true;
3060        } else  {
3061            // Process not otherwise of interest, it goes to the top of the non-service area.
3062            addIndex = mLruProcessServiceStart;
3063            if (client != null) {
3064                int clientIndex = mLruProcesses.lastIndexOf(client);
3065                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3066                        + app);
3067                if (clientIndex >= 0 && addIndex > clientIndex) {
3068                    addIndex = clientIndex;
3069                }
3070            }
3071            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3072        }
3073
3074        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3075                + mLruProcessActivityStart + "): " + app);
3076        */
3077
3078        if (lrui >= 0) {
3079            if (lrui < mLruProcessActivityStart) {
3080                mLruProcessActivityStart--;
3081            }
3082            if (lrui < mLruProcessServiceStart) {
3083                mLruProcessServiceStart--;
3084            }
3085            /*
3086            if (addIndex > lrui) {
3087                addIndex--;
3088            }
3089            if (nextIndex > lrui) {
3090                nextIndex--;
3091            }
3092            */
3093            mLruProcesses.remove(lrui);
3094        }
3095
3096        /*
3097        mLruProcesses.add(addIndex, app);
3098        if (inActivity) {
3099            mLruProcessActivityStart++;
3100        }
3101        if (inService) {
3102            mLruProcessActivityStart++;
3103        }
3104        */
3105
3106        int nextIndex;
3107        if (hasActivity) {
3108            final int N = mLruProcesses.size();
3109            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3110                // Process doesn't have activities, but has clients with
3111                // activities...  move it up, but one below the top (the top
3112                // should always have a real activity).
3113                if (DEBUG_LRU) Slog.d(TAG_LRU,
3114                        "Adding to second-top of LRU activity list: " + app);
3115                mLruProcesses.add(N - 1, app);
3116                // To keep it from spamming the LRU list (by making a bunch of clients),
3117                // we will push down any other entries owned by the app.
3118                final int uid = app.info.uid;
3119                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3120                    ProcessRecord subProc = mLruProcesses.get(i);
3121                    if (subProc.info.uid == uid) {
3122                        // We want to push this one down the list.  If the process after
3123                        // it is for the same uid, however, don't do so, because we don't
3124                        // want them internally to be re-ordered.
3125                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3126                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3127                                    "Pushing uid " + uid + " swapping at " + i + ": "
3128                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3129                            ProcessRecord tmp = mLruProcesses.get(i);
3130                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3131                            mLruProcesses.set(i - 1, tmp);
3132                            i--;
3133                        }
3134                    } else {
3135                        // A gap, we can stop here.
3136                        break;
3137                    }
3138                }
3139            } else {
3140                // Process has activities, put it at the very tipsy-top.
3141                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3142                mLruProcesses.add(app);
3143            }
3144            nextIndex = mLruProcessServiceStart;
3145        } else if (hasService) {
3146            // Process has services, put it at the top of the service list.
3147            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3148            mLruProcesses.add(mLruProcessActivityStart, app);
3149            nextIndex = mLruProcessServiceStart;
3150            mLruProcessActivityStart++;
3151        } else  {
3152            // Process not otherwise of interest, it goes to the top of the non-service area.
3153            int index = mLruProcessServiceStart;
3154            if (client != null) {
3155                // If there is a client, don't allow the process to be moved up higher
3156                // in the list than that client.
3157                int clientIndex = mLruProcesses.lastIndexOf(client);
3158                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3159                        + " when updating " + app);
3160                if (clientIndex <= lrui) {
3161                    // Don't allow the client index restriction to push it down farther in the
3162                    // list than it already is.
3163                    clientIndex = lrui;
3164                }
3165                if (clientIndex >= 0 && index > clientIndex) {
3166                    index = clientIndex;
3167                }
3168            }
3169            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3170            mLruProcesses.add(index, app);
3171            nextIndex = index-1;
3172            mLruProcessActivityStart++;
3173            mLruProcessServiceStart++;
3174        }
3175
3176        // If the app is currently using a content provider or service,
3177        // bump those processes as well.
3178        for (int j=app.connections.size()-1; j>=0; j--) {
3179            ConnectionRecord cr = app.connections.valueAt(j);
3180            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3181                    && cr.binding.service.app != null
3182                    && cr.binding.service.app.lruSeq != mLruSeq
3183                    && !cr.binding.service.app.persistent) {
3184                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3185                        "service connection", cr, app);
3186            }
3187        }
3188        for (int j=app.conProviders.size()-1; j>=0; j--) {
3189            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3190            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3191                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3192                        "provider reference", cpr, app);
3193            }
3194        }
3195    }
3196
3197    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3198        if (uid == Process.SYSTEM_UID) {
3199            // The system gets to run in any process.  If there are multiple
3200            // processes with the same uid, just pick the first (this
3201            // should never happen).
3202            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3203            if (procs == null) return null;
3204            final int procCount = procs.size();
3205            for (int i = 0; i < procCount; i++) {
3206                final int procUid = procs.keyAt(i);
3207                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3208                    // Don't use an app process or different user process for system component.
3209                    continue;
3210                }
3211                return procs.valueAt(i);
3212            }
3213        }
3214        ProcessRecord proc = mProcessNames.get(processName, uid);
3215        if (false && proc != null && !keepIfLarge
3216                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3217                && proc.lastCachedPss >= 4000) {
3218            // Turn this condition on to cause killing to happen regularly, for testing.
3219            if (proc.baseProcessTracker != null) {
3220                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3221            }
3222            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3223        } else if (proc != null && !keepIfLarge
3224                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3225                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3226            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3227            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3228                if (proc.baseProcessTracker != null) {
3229                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3230                }
3231                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3232            }
3233        }
3234        return proc;
3235    }
3236
3237    void notifyPackageUse(String packageName) {
3238        IPackageManager pm = AppGlobals.getPackageManager();
3239        try {
3240            pm.notifyPackageUse(packageName);
3241        } catch (RemoteException e) {
3242        }
3243    }
3244
3245    boolean isNextTransitionForward() {
3246        int transit = mWindowManager.getPendingAppTransition();
3247        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3248                || transit == AppTransition.TRANSIT_TASK_OPEN
3249                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3250    }
3251
3252    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3253            String processName, String abiOverride, int uid, Runnable crashHandler) {
3254        synchronized(this) {
3255            ApplicationInfo info = new ApplicationInfo();
3256            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3257            // For isolated processes, the former contains the parent's uid and the latter the
3258            // actual uid of the isolated process.
3259            // In the special case introduced by this method (which is, starting an isolated
3260            // process directly from the SystemServer without an actual parent app process) the
3261            // closest thing to a parent's uid is SYSTEM_UID.
3262            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3263            // the |isolated| logic in the ProcessRecord constructor.
3264            info.uid = Process.SYSTEM_UID;
3265            info.processName = processName;
3266            info.className = entryPoint;
3267            info.packageName = "android";
3268            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3269                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3270                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3271                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3272                    crashHandler);
3273            return proc != null ? proc.pid : 0;
3274        }
3275    }
3276
3277    final ProcessRecord startProcessLocked(String processName,
3278            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3279            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3280            boolean isolated, boolean keepIfLarge) {
3281        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3282                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3283                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3284                null /* crashHandler */);
3285    }
3286
3287    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3288            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3289            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3290            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3291        long startTime = SystemClock.elapsedRealtime();
3292        ProcessRecord app;
3293        if (!isolated) {
3294            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3295            checkTime(startTime, "startProcess: after getProcessRecord");
3296
3297            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3298                // If we are in the background, then check to see if this process
3299                // is bad.  If so, we will just silently fail.
3300                if (mAppErrors.isBadProcessLocked(info)) {
3301                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3302                            + "/" + info.processName);
3303                    return null;
3304                }
3305            } else {
3306                // When the user is explicitly starting a process, then clear its
3307                // crash count so that we won't make it bad until they see at
3308                // least one crash dialog again, and make the process good again
3309                // if it had been bad.
3310                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3311                        + "/" + info.processName);
3312                mAppErrors.resetProcessCrashTimeLocked(info);
3313                if (mAppErrors.isBadProcessLocked(info)) {
3314                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3315                            UserHandle.getUserId(info.uid), info.uid,
3316                            info.processName);
3317                    mAppErrors.clearBadProcessLocked(info);
3318                    if (app != null) {
3319                        app.bad = false;
3320                    }
3321                }
3322            }
3323        } else {
3324            // If this is an isolated process, it can't re-use an existing process.
3325            app = null;
3326        }
3327
3328        // app launch boost for big.little configurations
3329        // use cpusets to migrate freshly launched tasks to big cores
3330        synchronized(ActivityManagerService.this) {
3331            nativeMigrateToBoost();
3332            mIsBoosted = true;
3333            mBoostStartTime = SystemClock.uptimeMillis();
3334            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3335            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3336        }
3337
3338        // We don't have to do anything more if:
3339        // (1) There is an existing application record; and
3340        // (2) The caller doesn't think it is dead, OR there is no thread
3341        //     object attached to it so we know it couldn't have crashed; and
3342        // (3) There is a pid assigned to it, so it is either starting or
3343        //     already running.
3344        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3345                + " app=" + app + " knownToBeDead=" + knownToBeDead
3346                + " thread=" + (app != null ? app.thread : null)
3347                + " pid=" + (app != null ? app.pid : -1));
3348        if (app != null && app.pid > 0) {
3349            if (!knownToBeDead || app.thread == null) {
3350                // We already have the app running, or are waiting for it to
3351                // come up (we have a pid but not yet its thread), so keep it.
3352                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3353                // If this is a new package in the process, add the package to the list
3354                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3355                checkTime(startTime, "startProcess: done, added package to proc");
3356                return app;
3357            }
3358
3359            // An application record is attached to a previous process,
3360            // clean it up now.
3361            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3362            checkTime(startTime, "startProcess: bad proc running, killing");
3363            killProcessGroup(app.info.uid, app.pid);
3364            handleAppDiedLocked(app, true, true);
3365            checkTime(startTime, "startProcess: done killing old proc");
3366        }
3367
3368        String hostingNameStr = hostingName != null
3369                ? hostingName.flattenToShortString() : null;
3370
3371        if (app == null) {
3372            checkTime(startTime, "startProcess: creating new process record");
3373            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3374            if (app == null) {
3375                Slog.w(TAG, "Failed making new process record for "
3376                        + processName + "/" + info.uid + " isolated=" + isolated);
3377                return null;
3378            }
3379            app.crashHandler = crashHandler;
3380            checkTime(startTime, "startProcess: done creating new process record");
3381        } else {
3382            // If this is a new package in the process, add the package to the list
3383            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3384            checkTime(startTime, "startProcess: added package to existing proc");
3385        }
3386
3387        // If the system is not ready yet, then hold off on starting this
3388        // process until it is.
3389        if (!mProcessesReady
3390                && !isAllowedWhileBooting(info)
3391                && !allowWhileBooting) {
3392            if (!mProcessesOnHold.contains(app)) {
3393                mProcessesOnHold.add(app);
3394            }
3395            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3396                    "System not ready, putting on hold: " + app);
3397            checkTime(startTime, "startProcess: returning with proc on hold");
3398            return app;
3399        }
3400
3401        checkTime(startTime, "startProcess: stepping in to startProcess");
3402        startProcessLocked(
3403                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3404        checkTime(startTime, "startProcess: done starting proc!");
3405        return (app.pid != 0) ? app : null;
3406    }
3407
3408    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3409        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3410    }
3411
3412    private final void startProcessLocked(ProcessRecord app,
3413            String hostingType, String hostingNameStr) {
3414        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3415                null /* entryPoint */, null /* entryPointArgs */);
3416    }
3417
3418    private final void startProcessLocked(ProcessRecord app, String hostingType,
3419            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3420        long startTime = SystemClock.elapsedRealtime();
3421        if (app.pid > 0 && app.pid != MY_PID) {
3422            checkTime(startTime, "startProcess: removing from pids map");
3423            synchronized (mPidsSelfLocked) {
3424                mPidsSelfLocked.remove(app.pid);
3425                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3426            }
3427            checkTime(startTime, "startProcess: done removing from pids map");
3428            app.setPid(0);
3429        }
3430
3431        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3432                "startProcessLocked removing on hold: " + app);
3433        mProcessesOnHold.remove(app);
3434
3435        checkTime(startTime, "startProcess: starting to update cpu stats");
3436        updateCpuStats();
3437        checkTime(startTime, "startProcess: done updating cpu stats");
3438
3439        try {
3440            try {
3441                final int userId = UserHandle.getUserId(app.uid);
3442                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3443            } catch (RemoteException e) {
3444                throw e.rethrowAsRuntimeException();
3445            }
3446
3447            int uid = app.uid;
3448            int[] gids = null;
3449            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3450            if (!app.isolated) {
3451                int[] permGids = null;
3452                try {
3453                    checkTime(startTime, "startProcess: getting gids from package manager");
3454                    final IPackageManager pm = AppGlobals.getPackageManager();
3455                    permGids = pm.getPackageGids(app.info.packageName,
3456                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3457                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3458                            MountServiceInternal.class);
3459                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3460                            app.info.packageName);
3461                } catch (RemoteException e) {
3462                    throw e.rethrowAsRuntimeException();
3463                }
3464
3465                /*
3466                 * Add shared application and profile GIDs so applications can share some
3467                 * resources like shared libraries and access user-wide resources
3468                 */
3469                if (ArrayUtils.isEmpty(permGids)) {
3470                    gids = new int[2];
3471                } else {
3472                    gids = new int[permGids.length + 2];
3473                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3474                }
3475                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3476                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3477            }
3478            checkTime(startTime, "startProcess: building args");
3479            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3480                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3481                        && mTopComponent != null
3482                        && app.processName.equals(mTopComponent.getPackageName())) {
3483                    uid = 0;
3484                }
3485                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3486                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3487                    uid = 0;
3488                }
3489            }
3490            int debugFlags = 0;
3491            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3492                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3493                // Also turn on CheckJNI for debuggable apps. It's quite
3494                // awkward to turn on otherwise.
3495                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3496            }
3497            // Run the app in safe mode if its manifest requests so or the
3498            // system is booted in safe mode.
3499            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3500                mSafeMode == true) {
3501                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3502            }
3503            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3504                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3505            }
3506            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3507            if ("true".equals(genDebugInfoProperty)) {
3508                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3509            }
3510            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3511                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3512            }
3513            if ("1".equals(SystemProperties.get("debug.assert"))) {
3514                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3515            }
3516            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3517                // Enable all debug flags required by the native debugger.
3518                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3519                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3520                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3521                mNativeDebuggingApp = null;
3522            }
3523
3524            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3525            if (requiredAbi == null) {
3526                requiredAbi = Build.SUPPORTED_ABIS[0];
3527            }
3528
3529            String instructionSet = null;
3530            if (app.info.primaryCpuAbi != null) {
3531                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3532            }
3533
3534            app.gids = gids;
3535            app.requiredAbi = requiredAbi;
3536            app.instructionSet = instructionSet;
3537
3538            // Start the process.  It will either succeed and return a result containing
3539            // the PID of the new process, or else throw a RuntimeException.
3540            boolean isActivityProcess = (entryPoint == null);
3541            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3542            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3543                    app.processName);
3544            checkTime(startTime, "startProcess: asking zygote to start proc");
3545            Process.ProcessStartResult startResult = Process.start(entryPoint,
3546                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3547                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3548                    app.info.dataDir, entryPointArgs);
3549            checkTime(startTime, "startProcess: returned from zygote!");
3550            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3551
3552            if (app.isolated) {
3553                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3554            }
3555            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3556            checkTime(startTime, "startProcess: done updating battery stats");
3557
3558            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3559                    UserHandle.getUserId(uid), startResult.pid, uid,
3560                    app.processName, hostingType,
3561                    hostingNameStr != null ? hostingNameStr : "");
3562
3563            mProcessStartLogger.logIfNeededLocked(app, startResult);
3564
3565            if (app.persistent) {
3566                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3567            }
3568
3569            if (DEBUG_PROCESSES) {
3570                checkTime(startTime, "startProcess: building log message");
3571                StringBuilder buf = mStringBuilder;
3572                buf.setLength(0);
3573                buf.append("Start proc ");
3574                buf.append(startResult.pid);
3575                buf.append(':');
3576                buf.append(app.processName);
3577                buf.append('/');
3578                UserHandle.formatUid(buf, uid);
3579                if (!isActivityProcess) {
3580                    buf.append(" [");
3581                    buf.append(entryPoint);
3582                    buf.append("]");
3583                }
3584                buf.append(" for ");
3585                buf.append(hostingType);
3586                if (hostingNameStr != null) {
3587                    buf.append(" ");
3588                    buf.append(hostingNameStr);
3589                }
3590                Slog.i(TAG, buf.toString());
3591            }
3592            app.setPid(startResult.pid);
3593            app.usingWrapper = startResult.usingWrapper;
3594            app.removed = false;
3595            app.killed = false;
3596            app.killedByAm = false;
3597            checkTime(startTime, "startProcess: starting to update pids map");
3598            synchronized (mPidsSelfLocked) {
3599                this.mPidsSelfLocked.put(startResult.pid, app);
3600                if (isActivityProcess) {
3601                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3602                    msg.obj = app;
3603                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3604                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3605                }
3606            }
3607            checkTime(startTime, "startProcess: done updating pids map");
3608        } catch (RuntimeException e) {
3609            // XXX do better error recovery.
3610            app.setPid(0);
3611            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3612            if (app.isolated) {
3613                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3614            }
3615            Slog.e(TAG, "Failure starting process " + app.processName, e);
3616        }
3617    }
3618
3619    void updateUsageStats(ActivityRecord component, boolean resumed) {
3620        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3621                "updateUsageStats: comp=" + component + "res=" + resumed);
3622        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3623        if (resumed) {
3624            if (mUsageStatsService != null) {
3625                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3626                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3627            }
3628            synchronized (stats) {
3629                stats.noteActivityResumedLocked(component.app.uid);
3630            }
3631        } else {
3632            if (mUsageStatsService != null) {
3633                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3634                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3635            }
3636            synchronized (stats) {
3637                stats.noteActivityPausedLocked(component.app.uid);
3638            }
3639        }
3640    }
3641
3642    Intent getHomeIntent() {
3643        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3644        intent.setComponent(mTopComponent);
3645        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3646        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3647            intent.addCategory(Intent.CATEGORY_HOME);
3648        }
3649        return intent;
3650    }
3651
3652    boolean startHomeActivityLocked(int userId, String reason) {
3653        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3654                && mTopAction == null) {
3655            // We are running in factory test mode, but unable to find
3656            // the factory test app, so just sit around displaying the
3657            // error message and don't try to start anything.
3658            return false;
3659        }
3660        Intent intent = getHomeIntent();
3661        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3662        if (aInfo != null) {
3663            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3664            // Don't do this if the home app is currently being
3665            // instrumented.
3666            aInfo = new ActivityInfo(aInfo);
3667            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3668            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3669                    aInfo.applicationInfo.uid, true);
3670            if (app == null || app.instrumentationClass == null) {
3671                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3672                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3673            }
3674        }
3675
3676        return true;
3677    }
3678
3679    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3680        ActivityInfo ai = null;
3681        ComponentName comp = intent.getComponent();
3682        try {
3683            if (comp != null) {
3684                // Factory test.
3685                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3686            } else {
3687                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3688                        intent,
3689                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3690                        flags, userId);
3691
3692                if (info != null) {
3693                    ai = info.activityInfo;
3694                }
3695            }
3696        } catch (RemoteException e) {
3697            // ignore
3698        }
3699
3700        return ai;
3701    }
3702
3703    /**
3704     * Starts the "new version setup screen" if appropriate.
3705     */
3706    void startSetupActivityLocked() {
3707        // Only do this once per boot.
3708        if (mCheckedForSetup) {
3709            return;
3710        }
3711
3712        // We will show this screen if the current one is a different
3713        // version than the last one shown, and we are not running in
3714        // low-level factory test mode.
3715        final ContentResolver resolver = mContext.getContentResolver();
3716        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3717                Settings.Global.getInt(resolver,
3718                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3719            mCheckedForSetup = true;
3720
3721            // See if we should be showing the platform update setup UI.
3722            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3723            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3724                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3725            if (!ris.isEmpty()) {
3726                final ResolveInfo ri = ris.get(0);
3727                String vers = ri.activityInfo.metaData != null
3728                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3729                        : null;
3730                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3731                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3732                            Intent.METADATA_SETUP_VERSION);
3733                }
3734                String lastVers = Settings.Secure.getString(
3735                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3736                if (vers != null && !vers.equals(lastVers)) {
3737                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3738                    intent.setComponent(new ComponentName(
3739                            ri.activityInfo.packageName, ri.activityInfo.name));
3740                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3741                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3742                            null, 0, 0, 0, null, false, false, null, null, null);
3743                }
3744            }
3745        }
3746    }
3747
3748    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3749        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3750    }
3751
3752    void enforceNotIsolatedCaller(String caller) {
3753        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3754            throw new SecurityException("Isolated process not allowed to call " + caller);
3755        }
3756    }
3757
3758    void enforceShellRestriction(String restriction, int userHandle) {
3759        if (Binder.getCallingUid() == Process.SHELL_UID) {
3760            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3761                throw new SecurityException("Shell does not have permission to access user "
3762                        + userHandle);
3763            }
3764        }
3765    }
3766
3767    @Override
3768    public int getFrontActivityScreenCompatMode() {
3769        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3770        synchronized (this) {
3771            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3772        }
3773    }
3774
3775    @Override
3776    public void setFrontActivityScreenCompatMode(int mode) {
3777        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3778                "setFrontActivityScreenCompatMode");
3779        synchronized (this) {
3780            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3781        }
3782    }
3783
3784    @Override
3785    public int getPackageScreenCompatMode(String packageName) {
3786        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3787        synchronized (this) {
3788            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3789        }
3790    }
3791
3792    @Override
3793    public void setPackageScreenCompatMode(String packageName, int mode) {
3794        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3795                "setPackageScreenCompatMode");
3796        synchronized (this) {
3797            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3798        }
3799    }
3800
3801    @Override
3802    public boolean getPackageAskScreenCompat(String packageName) {
3803        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3804        synchronized (this) {
3805            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3806        }
3807    }
3808
3809    @Override
3810    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3811        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3812                "setPackageAskScreenCompat");
3813        synchronized (this) {
3814            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3815        }
3816    }
3817
3818    private boolean hasUsageStatsPermission(String callingPackage) {
3819        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3820                Binder.getCallingUid(), callingPackage);
3821        if (mode == AppOpsManager.MODE_DEFAULT) {
3822            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3823                    == PackageManager.PERMISSION_GRANTED;
3824        }
3825        return mode == AppOpsManager.MODE_ALLOWED;
3826    }
3827
3828    @Override
3829    public int getPackageProcessState(String packageName, String callingPackage) {
3830        if (!hasUsageStatsPermission(callingPackage)) {
3831            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3832                    "getPackageProcessState");
3833        }
3834
3835        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3836        synchronized (this) {
3837            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3838                final ProcessRecord proc = mLruProcesses.get(i);
3839                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3840                        || procState > proc.setProcState) {
3841                    boolean found = false;
3842                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3843                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3844                            procState = proc.setProcState;
3845                            found = true;
3846                        }
3847                    }
3848                    if (proc.pkgDeps != null && !found) {
3849                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3850                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3851                                procState = proc.setProcState;
3852                                break;
3853                            }
3854                        }
3855                    }
3856                }
3857            }
3858        }
3859        return procState;
3860    }
3861
3862    @Override
3863    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3864        synchronized (this) {
3865            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3866            if (app == null) {
3867                return false;
3868            }
3869            if (app.trimMemoryLevel < level && app.thread != null &&
3870                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3871                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3872                try {
3873                    app.thread.scheduleTrimMemory(level);
3874                    app.trimMemoryLevel = level;
3875                    return true;
3876                } catch (RemoteException e) {
3877                    // Fallthrough to failure case.
3878                }
3879            }
3880        }
3881        return false;
3882    }
3883
3884    private void dispatchProcessesChanged() {
3885        int N;
3886        synchronized (this) {
3887            N = mPendingProcessChanges.size();
3888            if (mActiveProcessChanges.length < N) {
3889                mActiveProcessChanges = new ProcessChangeItem[N];
3890            }
3891            mPendingProcessChanges.toArray(mActiveProcessChanges);
3892            mPendingProcessChanges.clear();
3893            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3894                    "*** Delivering " + N + " process changes");
3895        }
3896
3897        int i = mProcessObservers.beginBroadcast();
3898        while (i > 0) {
3899            i--;
3900            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3901            if (observer != null) {
3902                try {
3903                    for (int j=0; j<N; j++) {
3904                        ProcessChangeItem item = mActiveProcessChanges[j];
3905                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3906                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3907                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3908                                    + item.uid + ": " + item.foregroundActivities);
3909                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3910                                    item.foregroundActivities);
3911                        }
3912                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3913                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3914                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3915                                    + ": " + item.processState);
3916                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3917                        }
3918                    }
3919                } catch (RemoteException e) {
3920                }
3921            }
3922        }
3923        mProcessObservers.finishBroadcast();
3924
3925        synchronized (this) {
3926            for (int j=0; j<N; j++) {
3927                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3928            }
3929        }
3930    }
3931
3932    private void dispatchProcessDied(int pid, int uid) {
3933        int i = mProcessObservers.beginBroadcast();
3934        while (i > 0) {
3935            i--;
3936            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3937            if (observer != null) {
3938                try {
3939                    observer.onProcessDied(pid, uid);
3940                } catch (RemoteException e) {
3941                }
3942            }
3943        }
3944        mProcessObservers.finishBroadcast();
3945    }
3946
3947    private void dispatchUidsChanged() {
3948        int N;
3949        synchronized (this) {
3950            N = mPendingUidChanges.size();
3951            if (mActiveUidChanges.length < N) {
3952                mActiveUidChanges = new UidRecord.ChangeItem[N];
3953            }
3954            for (int i=0; i<N; i++) {
3955                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3956                mActiveUidChanges[i] = change;
3957                if (change.uidRecord != null) {
3958                    change.uidRecord.pendingChange = null;
3959                    change.uidRecord = null;
3960                }
3961            }
3962            mPendingUidChanges.clear();
3963            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3964                    "*** Delivering " + N + " uid changes");
3965        }
3966
3967        if (mLocalPowerManager != null) {
3968            for (int j=0; j<N; j++) {
3969                UidRecord.ChangeItem item = mActiveUidChanges[j];
3970                if (item.change == UidRecord.CHANGE_GONE
3971                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3972                    mLocalPowerManager.uidGone(item.uid);
3973                } else {
3974                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3975                }
3976            }
3977        }
3978
3979        int i = mUidObservers.beginBroadcast();
3980        while (i > 0) {
3981            i--;
3982            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3983            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3984            if (observer != null) {
3985                try {
3986                    for (int j=0; j<N; j++) {
3987                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3988                        final int change = item.change;
3989                        UidRecord validateUid = null;
3990                        if (VALIDATE_UID_STATES && i == 0) {
3991                            validateUid = mValidateUids.get(item.uid);
3992                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3993                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3994                                validateUid = new UidRecord(item.uid);
3995                                mValidateUids.put(item.uid, validateUid);
3996                            }
3997                        }
3998                        if (change == UidRecord.CHANGE_IDLE
3999                                || change == UidRecord.CHANGE_GONE_IDLE) {
4000                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4001                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4002                                        "UID idle uid=" + item.uid);
4003                                observer.onUidIdle(item.uid);
4004                            }
4005                            if (VALIDATE_UID_STATES && i == 0) {
4006                                if (validateUid != null) {
4007                                    validateUid.idle = true;
4008                                }
4009                            }
4010                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4011                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4012                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4013                                        "UID active uid=" + item.uid);
4014                                observer.onUidActive(item.uid);
4015                            }
4016                            if (VALIDATE_UID_STATES && i == 0) {
4017                                validateUid.idle = false;
4018                            }
4019                        }
4020                        if (change == UidRecord.CHANGE_GONE
4021                                || change == UidRecord.CHANGE_GONE_IDLE) {
4022                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4023                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4024                                        "UID gone uid=" + item.uid);
4025                                observer.onUidGone(item.uid);
4026                            }
4027                            if (VALIDATE_UID_STATES && i == 0) {
4028                                if (validateUid != null) {
4029                                    mValidateUids.remove(item.uid);
4030                                }
4031                            }
4032                        } else {
4033                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4034                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4035                                        "UID CHANGED uid=" + item.uid
4036                                                + ": " + item.processState);
4037                                observer.onUidStateChanged(item.uid, item.processState);
4038                            }
4039                            if (VALIDATE_UID_STATES && i == 0) {
4040                                validateUid.curProcState = validateUid.setProcState
4041                                        = item.processState;
4042                            }
4043                        }
4044                    }
4045                } catch (RemoteException e) {
4046                }
4047            }
4048        }
4049        mUidObservers.finishBroadcast();
4050
4051        synchronized (this) {
4052            for (int j=0; j<N; j++) {
4053                mAvailUidChanges.add(mActiveUidChanges[j]);
4054            }
4055        }
4056    }
4057
4058    @Override
4059    public final int startActivity(IApplicationThread caller, String callingPackage,
4060            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4061            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4062        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4063                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4064                UserHandle.getCallingUserId());
4065    }
4066
4067    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4068        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4069        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4070                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4071                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4072
4073        // TODO: Switch to user app stacks here.
4074        String mimeType = intent.getType();
4075        final Uri data = intent.getData();
4076        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4077            mimeType = getProviderMimeType(data, userId);
4078        }
4079        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4080
4081        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4082        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4083                null, 0, 0, null, null, null, null, false, userId, container, null);
4084    }
4085
4086    @Override
4087    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4088            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4089            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4090        enforceNotIsolatedCaller("startActivity");
4091        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4092                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4093        // TODO: Switch to user app stacks here.
4094        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4095                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4096                profilerInfo, null, null, bOptions, false, userId, null, null);
4097    }
4098
4099    @Override
4100    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4101            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4102            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4103            int userId) {
4104
4105        // This is very dangerous -- it allows you to perform a start activity (including
4106        // permission grants) as any app that may launch one of your own activities.  So
4107        // we will only allow this to be done from activities that are part of the core framework,
4108        // and then only when they are running as the system.
4109        final ActivityRecord sourceRecord;
4110        final int targetUid;
4111        final String targetPackage;
4112        synchronized (this) {
4113            if (resultTo == null) {
4114                throw new SecurityException("Must be called from an activity");
4115            }
4116            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4117            if (sourceRecord == null) {
4118                throw new SecurityException("Called with bad activity token: " + resultTo);
4119            }
4120            if (!sourceRecord.info.packageName.equals("android")) {
4121                throw new SecurityException(
4122                        "Must be called from an activity that is declared in the android package");
4123            }
4124            if (sourceRecord.app == null) {
4125                throw new SecurityException("Called without a process attached to activity");
4126            }
4127            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4128                // This is still okay, as long as this activity is running under the
4129                // uid of the original calling activity.
4130                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4131                    throw new SecurityException(
4132                            "Calling activity in uid " + sourceRecord.app.uid
4133                                    + " must be system uid or original calling uid "
4134                                    + sourceRecord.launchedFromUid);
4135                }
4136            }
4137            if (ignoreTargetSecurity) {
4138                if (intent.getComponent() == null) {
4139                    throw new SecurityException(
4140                            "Component must be specified with ignoreTargetSecurity");
4141                }
4142                if (intent.getSelector() != null) {
4143                    throw new SecurityException(
4144                            "Selector not allowed with ignoreTargetSecurity");
4145                }
4146            }
4147            targetUid = sourceRecord.launchedFromUid;
4148            targetPackage = sourceRecord.launchedFromPackage;
4149        }
4150
4151        if (userId == UserHandle.USER_NULL) {
4152            userId = UserHandle.getUserId(sourceRecord.app.uid);
4153        }
4154
4155        // TODO: Switch to user app stacks here.
4156        try {
4157            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4158                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4159                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4160            return ret;
4161        } catch (SecurityException e) {
4162            // XXX need to figure out how to propagate to original app.
4163            // A SecurityException here is generally actually a fault of the original
4164            // calling activity (such as a fairly granting permissions), so propagate it
4165            // back to them.
4166            /*
4167            StringBuilder msg = new StringBuilder();
4168            msg.append("While launching");
4169            msg.append(intent.toString());
4170            msg.append(": ");
4171            msg.append(e.getMessage());
4172            */
4173            throw e;
4174        }
4175    }
4176
4177    @Override
4178    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4179            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4180            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4181        enforceNotIsolatedCaller("startActivityAndWait");
4182        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4183                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4184        WaitResult res = new WaitResult();
4185        // TODO: Switch to user app stacks here.
4186        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4187                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4188                bOptions, false, userId, null, null);
4189        return res;
4190    }
4191
4192    @Override
4193    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4194            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4195            int startFlags, Configuration config, Bundle bOptions, int userId) {
4196        enforceNotIsolatedCaller("startActivityWithConfig");
4197        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4198                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4199        // TODO: Switch to user app stacks here.
4200        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4201                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4202                null, null, config, bOptions, false, userId, null, null);
4203        return ret;
4204    }
4205
4206    @Override
4207    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4208            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4209            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4210            throws TransactionTooLargeException {
4211        enforceNotIsolatedCaller("startActivityIntentSender");
4212        // Refuse possible leaked file descriptors
4213        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4214            throw new IllegalArgumentException("File descriptors passed in Intent");
4215        }
4216
4217        IIntentSender sender = intent.getTarget();
4218        if (!(sender instanceof PendingIntentRecord)) {
4219            throw new IllegalArgumentException("Bad PendingIntent object");
4220        }
4221
4222        PendingIntentRecord pir = (PendingIntentRecord)sender;
4223
4224        synchronized (this) {
4225            // If this is coming from the currently resumed activity, it is
4226            // effectively saying that app switches are allowed at this point.
4227            final ActivityStack stack = getFocusedStack();
4228            if (stack.mResumedActivity != null &&
4229                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4230                mAppSwitchesAllowedTime = 0;
4231            }
4232        }
4233        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4234                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4235        return ret;
4236    }
4237
4238    @Override
4239    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4240            Intent intent, String resolvedType, IVoiceInteractionSession session,
4241            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4242            Bundle bOptions, int userId) {
4243        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4244                != PackageManager.PERMISSION_GRANTED) {
4245            String msg = "Permission Denial: startVoiceActivity() from pid="
4246                    + Binder.getCallingPid()
4247                    + ", uid=" + Binder.getCallingUid()
4248                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4249            Slog.w(TAG, msg);
4250            throw new SecurityException(msg);
4251        }
4252        if (session == null || interactor == null) {
4253            throw new NullPointerException("null session or interactor");
4254        }
4255        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4256                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4257        // TODO: Switch to user app stacks here.
4258        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4259                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4260                null, bOptions, false, userId, null, null);
4261    }
4262
4263    @Override
4264    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4265            throws RemoteException {
4266        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4267        synchronized (this) {
4268            ActivityRecord activity = getFocusedStack().topActivity();
4269            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4270                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4271            }
4272            if (mRunningVoice != null || activity.task.voiceSession != null
4273                    || activity.voiceSession != null) {
4274                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4275                return;
4276            }
4277            if (activity.pendingVoiceInteractionStart) {
4278                Slog.w(TAG, "Pending start of voice interaction already.");
4279                return;
4280            }
4281            activity.pendingVoiceInteractionStart = true;
4282        }
4283        LocalServices.getService(VoiceInteractionManagerInternal.class)
4284                .startLocalVoiceInteraction(callingActivity, options);
4285    }
4286
4287    @Override
4288    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4289        LocalServices.getService(VoiceInteractionManagerInternal.class)
4290                .stopLocalVoiceInteraction(callingActivity);
4291    }
4292
4293    @Override
4294    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4295        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4296                .supportsLocalVoiceInteraction();
4297    }
4298
4299    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4300            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4301        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4302        if (activityToCallback == null) return;
4303        activityToCallback.setVoiceSessionLocked(voiceSession);
4304
4305        // Inform the activity
4306        try {
4307            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4308                    voiceInteractor);
4309            long token = Binder.clearCallingIdentity();
4310            try {
4311                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4312            } finally {
4313                Binder.restoreCallingIdentity(token);
4314            }
4315            // TODO: VI Should we cache the activity so that it's easier to find later
4316            // rather than scan through all the stacks and activities?
4317        } catch (RemoteException re) {
4318            activityToCallback.clearVoiceSessionLocked();
4319            // TODO: VI Should this terminate the voice session?
4320        }
4321    }
4322
4323    @Override
4324    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4325        synchronized (this) {
4326            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4327                if (keepAwake) {
4328                    mVoiceWakeLock.acquire();
4329                } else {
4330                    mVoiceWakeLock.release();
4331                }
4332            }
4333        }
4334    }
4335
4336    @Override
4337    public boolean startNextMatchingActivity(IBinder callingActivity,
4338            Intent intent, Bundle bOptions) {
4339        // Refuse possible leaked file descriptors
4340        if (intent != null && intent.hasFileDescriptors() == true) {
4341            throw new IllegalArgumentException("File descriptors passed in Intent");
4342        }
4343        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4344
4345        synchronized (this) {
4346            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4347            if (r == null) {
4348                ActivityOptions.abort(options);
4349                return false;
4350            }
4351            if (r.app == null || r.app.thread == null) {
4352                // The caller is not running...  d'oh!
4353                ActivityOptions.abort(options);
4354                return false;
4355            }
4356            intent = new Intent(intent);
4357            // The caller is not allowed to change the data.
4358            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4359            // And we are resetting to find the next component...
4360            intent.setComponent(null);
4361
4362            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4363
4364            ActivityInfo aInfo = null;
4365            try {
4366                List<ResolveInfo> resolves =
4367                    AppGlobals.getPackageManager().queryIntentActivities(
4368                            intent, r.resolvedType,
4369                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4370                            UserHandle.getCallingUserId());
4371
4372                // Look for the original activity in the list...
4373                final int N = resolves != null ? resolves.size() : 0;
4374                for (int i=0; i<N; i++) {
4375                    ResolveInfo rInfo = resolves.get(i);
4376                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4377                            && rInfo.activityInfo.name.equals(r.info.name)) {
4378                        // We found the current one...  the next matching is
4379                        // after it.
4380                        i++;
4381                        if (i<N) {
4382                            aInfo = resolves.get(i).activityInfo;
4383                        }
4384                        if (debug) {
4385                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4386                                    + "/" + r.info.name);
4387                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4388                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4389                        }
4390                        break;
4391                    }
4392                }
4393            } catch (RemoteException e) {
4394            }
4395
4396            if (aInfo == null) {
4397                // Nobody who is next!
4398                ActivityOptions.abort(options);
4399                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4400                return false;
4401            }
4402
4403            intent.setComponent(new ComponentName(
4404                    aInfo.applicationInfo.packageName, aInfo.name));
4405            intent.setFlags(intent.getFlags()&~(
4406                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4407                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4408                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4409                    Intent.FLAG_ACTIVITY_NEW_TASK));
4410
4411            // Okay now we need to start the new activity, replacing the
4412            // currently running activity.  This is a little tricky because
4413            // we want to start the new one as if the current one is finished,
4414            // but not finish the current one first so that there is no flicker.
4415            // And thus...
4416            final boolean wasFinishing = r.finishing;
4417            r.finishing = true;
4418
4419            // Propagate reply information over to the new activity.
4420            final ActivityRecord resultTo = r.resultTo;
4421            final String resultWho = r.resultWho;
4422            final int requestCode = r.requestCode;
4423            r.resultTo = null;
4424            if (resultTo != null) {
4425                resultTo.removeResultsLocked(r, resultWho, requestCode);
4426            }
4427
4428            final long origId = Binder.clearCallingIdentity();
4429            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4430                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4431                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4432                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4433                    false, false, null, null, null);
4434            Binder.restoreCallingIdentity(origId);
4435
4436            r.finishing = wasFinishing;
4437            if (res != ActivityManager.START_SUCCESS) {
4438                return false;
4439            }
4440            return true;
4441        }
4442    }
4443
4444    @Override
4445    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4446        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4447            String msg = "Permission Denial: startActivityFromRecents called without " +
4448                    START_TASKS_FROM_RECENTS;
4449            Slog.w(TAG, msg);
4450            throw new SecurityException(msg);
4451        }
4452        final long origId = Binder.clearCallingIdentity();
4453        try {
4454            return startActivityFromRecentsInner(taskId, bOptions);
4455        } finally {
4456            Binder.restoreCallingIdentity(origId);
4457        }
4458    }
4459
4460    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4461        final TaskRecord task;
4462        final int callingUid;
4463        final String callingPackage;
4464        final Intent intent;
4465        final int userId;
4466        synchronized (this) {
4467            final ActivityOptions activityOptions = (bOptions != null)
4468                    ? new ActivityOptions(bOptions) : null;
4469            final int launchStackId = (activityOptions != null)
4470                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4471
4472            if (launchStackId == HOME_STACK_ID) {
4473                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4474                        + taskId + " can't be launch in the home stack.");
4475            }
4476            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4477            if (task == null) {
4478                throw new IllegalArgumentException(
4479                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4480            }
4481
4482            if (launchStackId != INVALID_STACK_ID) {
4483                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4484                    mWindowManager.setDockedStackCreateState(
4485                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4486                }
4487                if (task.stack.mStackId != launchStackId) {
4488                    mStackSupervisor.moveTaskToStackLocked(
4489                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4490                            ANIMATE);
4491                }
4492            }
4493
4494            // If the user must confirm credentials (e.g. when first launching a work app and the
4495            // Work Challenge is present) let startActivityInPackage handle the intercepting.
4496            if (!mUserController.shouldConfirmCredentials(task.userId)
4497                    && task.getRootActivity() != null) {
4498                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4499                return ActivityManager.START_TASK_TO_FRONT;
4500            }
4501            callingUid = task.mCallingUid;
4502            callingPackage = task.mCallingPackage;
4503            intent = task.intent;
4504            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4505            userId = task.userId;
4506        }
4507        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4508                bOptions, userId, null, task);
4509    }
4510
4511    final int startActivityInPackage(int uid, String callingPackage,
4512            Intent intent, String resolvedType, IBinder resultTo,
4513            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4514            IActivityContainer container, TaskRecord inTask) {
4515
4516        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4517                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4518
4519        // TODO: Switch to user app stacks here.
4520        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4521                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4522                null, null, null, bOptions, false, userId, container, inTask);
4523        return ret;
4524    }
4525
4526    @Override
4527    public final int startActivities(IApplicationThread caller, String callingPackage,
4528            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4529            int userId) {
4530        enforceNotIsolatedCaller("startActivities");
4531        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4532                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4533        // TODO: Switch to user app stacks here.
4534        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4535                resolvedTypes, resultTo, bOptions, userId);
4536        return ret;
4537    }
4538
4539    final int startActivitiesInPackage(int uid, String callingPackage,
4540            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4541            Bundle bOptions, int userId) {
4542
4543        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4544                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4545        // TODO: Switch to user app stacks here.
4546        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4547                resultTo, bOptions, userId);
4548        return ret;
4549    }
4550
4551    @Override
4552    public void reportActivityFullyDrawn(IBinder token) {
4553        synchronized (this) {
4554            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4555            if (r == null) {
4556                return;
4557            }
4558            r.reportFullyDrawnLocked();
4559        }
4560    }
4561
4562    @Override
4563    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4564        synchronized (this) {
4565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4566            if (r == null) {
4567                return;
4568            }
4569            TaskRecord task = r.task;
4570            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4571                // Fixed screen orientation isn't supported when activities aren't in full screen
4572                // mode.
4573                return;
4574            }
4575            final long origId = Binder.clearCallingIdentity();
4576            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4577            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4578                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4579            if (config != null) {
4580                r.frozenBeforeDestroy = true;
4581                if (!updateConfigurationLocked(config, r, false)) {
4582                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4583                }
4584            }
4585            Binder.restoreCallingIdentity(origId);
4586        }
4587    }
4588
4589    @Override
4590    public int getRequestedOrientation(IBinder token) {
4591        synchronized (this) {
4592            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4593            if (r == null) {
4594                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4595            }
4596            return mWindowManager.getAppOrientation(r.appToken);
4597        }
4598    }
4599
4600    /**
4601     * This is the internal entry point for handling Activity.finish().
4602     *
4603     * @param token The Binder token referencing the Activity we want to finish.
4604     * @param resultCode Result code, if any, from this Activity.
4605     * @param resultData Result data (Intent), if any, from this Activity.
4606     * @param finishTask Whether to finish the task associated with this Activity.
4607     *
4608     * @return Returns true if the activity successfully finished, or false if it is still running.
4609     */
4610    @Override
4611    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4612            int finishTask) {
4613        // Refuse possible leaked file descriptors
4614        if (resultData != null && resultData.hasFileDescriptors() == true) {
4615            throw new IllegalArgumentException("File descriptors passed in Intent");
4616        }
4617
4618        synchronized(this) {
4619            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4620            if (r == null) {
4621                return true;
4622            }
4623            // Keep track of the root activity of the task before we finish it
4624            TaskRecord tr = r.task;
4625            ActivityRecord rootR = tr.getRootActivity();
4626            if (rootR == null) {
4627                Slog.w(TAG, "Finishing task with all activities already finished");
4628            }
4629            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4630            // finish.
4631            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4632                    mStackSupervisor.isLastLockedTask(tr)) {
4633                Slog.i(TAG, "Not finishing task in lock task mode");
4634                mStackSupervisor.showLockTaskToast();
4635                return false;
4636            }
4637            if (mController != null) {
4638                // Find the first activity that is not finishing.
4639                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4640                if (next != null) {
4641                    // ask watcher if this is allowed
4642                    boolean resumeOK = true;
4643                    try {
4644                        resumeOK = mController.activityResuming(next.packageName);
4645                    } catch (RemoteException e) {
4646                        mController = null;
4647                        Watchdog.getInstance().setActivityController(null);
4648                    }
4649
4650                    if (!resumeOK) {
4651                        Slog.i(TAG, "Not finishing activity because controller resumed");
4652                        return false;
4653                    }
4654                }
4655            }
4656            final long origId = Binder.clearCallingIdentity();
4657            try {
4658                boolean res;
4659                final boolean finishWithRootActivity =
4660                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4661                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4662                        || (finishWithRootActivity && r == rootR)) {
4663                    // If requested, remove the task that is associated to this activity only if it
4664                    // was the root activity in the task. The result code and data is ignored
4665                    // because we don't support returning them across task boundaries. Also, to
4666                    // keep backwards compatibility we remove the task from recents when finishing
4667                    // task with root activity.
4668                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4669                    if (!res) {
4670                        Slog.i(TAG, "Removing task failed to finish activity");
4671                    }
4672                } else {
4673                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4674                            resultData, "app-request", true);
4675                    if (!res) {
4676                        Slog.i(TAG, "Failed to finish by app-request");
4677                    }
4678                }
4679                return res;
4680            } finally {
4681                Binder.restoreCallingIdentity(origId);
4682            }
4683        }
4684    }
4685
4686    @Override
4687    public final void finishHeavyWeightApp() {
4688        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4689                != PackageManager.PERMISSION_GRANTED) {
4690            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4691                    + Binder.getCallingPid()
4692                    + ", uid=" + Binder.getCallingUid()
4693                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4694            Slog.w(TAG, msg);
4695            throw new SecurityException(msg);
4696        }
4697
4698        synchronized(this) {
4699            if (mHeavyWeightProcess == null) {
4700                return;
4701            }
4702
4703            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4704            for (int i = 0; i < activities.size(); i++) {
4705                ActivityRecord r = activities.get(i);
4706                if (!r.finishing && r.isInStackLocked()) {
4707                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4708                            null, "finish-heavy", true);
4709                }
4710            }
4711
4712            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4713                    mHeavyWeightProcess.userId, 0));
4714            mHeavyWeightProcess = null;
4715        }
4716    }
4717
4718    @Override
4719    public void crashApplication(int uid, int initialPid, String packageName,
4720            String message) {
4721        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4722                != PackageManager.PERMISSION_GRANTED) {
4723            String msg = "Permission Denial: crashApplication() from pid="
4724                    + Binder.getCallingPid()
4725                    + ", uid=" + Binder.getCallingUid()
4726                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4727            Slog.w(TAG, msg);
4728            throw new SecurityException(msg);
4729        }
4730
4731        synchronized(this) {
4732            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4733        }
4734    }
4735
4736    @Override
4737    public final void finishSubActivity(IBinder token, String resultWho,
4738            int requestCode) {
4739        synchronized(this) {
4740            final long origId = Binder.clearCallingIdentity();
4741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4742            if (r != null) {
4743                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4744            }
4745            Binder.restoreCallingIdentity(origId);
4746        }
4747    }
4748
4749    @Override
4750    public boolean finishActivityAffinity(IBinder token) {
4751        synchronized(this) {
4752            final long origId = Binder.clearCallingIdentity();
4753            try {
4754                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4755                if (r == null) {
4756                    return false;
4757                }
4758
4759                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4760                // can finish.
4761                final TaskRecord task = r.task;
4762                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4763                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4764                    mStackSupervisor.showLockTaskToast();
4765                    return false;
4766                }
4767                return task.stack.finishActivityAffinityLocked(r);
4768            } finally {
4769                Binder.restoreCallingIdentity(origId);
4770            }
4771        }
4772    }
4773
4774    @Override
4775    public void finishVoiceTask(IVoiceInteractionSession session) {
4776        synchronized (this) {
4777            final long origId = Binder.clearCallingIdentity();
4778            try {
4779                // TODO: VI Consider treating local voice interactions and voice tasks
4780                // differently here
4781                mStackSupervisor.finishVoiceTask(session);
4782            } finally {
4783                Binder.restoreCallingIdentity(origId);
4784            }
4785        }
4786
4787    }
4788
4789    @Override
4790    public boolean releaseActivityInstance(IBinder token) {
4791        synchronized(this) {
4792            final long origId = Binder.clearCallingIdentity();
4793            try {
4794                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4795                if (r == null) {
4796                    return false;
4797                }
4798                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4799            } finally {
4800                Binder.restoreCallingIdentity(origId);
4801            }
4802        }
4803    }
4804
4805    @Override
4806    public void releaseSomeActivities(IApplicationThread appInt) {
4807        synchronized(this) {
4808            final long origId = Binder.clearCallingIdentity();
4809            try {
4810                ProcessRecord app = getRecordForAppLocked(appInt);
4811                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4812            } finally {
4813                Binder.restoreCallingIdentity(origId);
4814            }
4815        }
4816    }
4817
4818    @Override
4819    public boolean willActivityBeVisible(IBinder token) {
4820        synchronized(this) {
4821            ActivityStack stack = ActivityRecord.getStackLocked(token);
4822            if (stack != null) {
4823                return stack.willActivityBeVisibleLocked(token);
4824            }
4825            return false;
4826        }
4827    }
4828
4829    @Override
4830    public void overridePendingTransition(IBinder token, String packageName,
4831            int enterAnim, int exitAnim) {
4832        synchronized(this) {
4833            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4834            if (self == null) {
4835                return;
4836            }
4837
4838            final long origId = Binder.clearCallingIdentity();
4839
4840            if (self.state == ActivityState.RESUMED
4841                    || self.state == ActivityState.PAUSING) {
4842                mWindowManager.overridePendingAppTransition(packageName,
4843                        enterAnim, exitAnim, null);
4844            }
4845
4846            Binder.restoreCallingIdentity(origId);
4847        }
4848    }
4849
4850    /**
4851     * Main function for removing an existing process from the activity manager
4852     * as a result of that process going away.  Clears out all connections
4853     * to the process.
4854     */
4855    private final void handleAppDiedLocked(ProcessRecord app,
4856            boolean restarting, boolean allowRestart) {
4857        int pid = app.pid;
4858        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4859        if (!kept && !restarting) {
4860            removeLruProcessLocked(app);
4861            if (pid > 0) {
4862                ProcessList.remove(pid);
4863            }
4864        }
4865
4866        if (mProfileProc == app) {
4867            clearProfilerLocked();
4868        }
4869
4870        // Remove this application's activities from active lists.
4871        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4872
4873        app.activities.clear();
4874
4875        if (app.instrumentationClass != null) {
4876            Slog.w(TAG, "Crash of app " + app.processName
4877                  + " running instrumentation " + app.instrumentationClass);
4878            Bundle info = new Bundle();
4879            info.putString("shortMsg", "Process crashed.");
4880            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4881        }
4882
4883        if (!restarting && hasVisibleActivities
4884                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4885            // If there was nothing to resume, and we are not already restarting this process, but
4886            // there is a visible activity that is hosted by the process...  then make sure all
4887            // visible activities are running, taking care of restarting this process.
4888            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4889        }
4890    }
4891
4892    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4893        IBinder threadBinder = thread.asBinder();
4894        // Find the application record.
4895        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4896            ProcessRecord rec = mLruProcesses.get(i);
4897            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4898                return i;
4899            }
4900        }
4901        return -1;
4902    }
4903
4904    final ProcessRecord getRecordForAppLocked(
4905            IApplicationThread thread) {
4906        if (thread == null) {
4907            return null;
4908        }
4909
4910        int appIndex = getLRURecordIndexForAppLocked(thread);
4911        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4912    }
4913
4914    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4915        // If there are no longer any background processes running,
4916        // and the app that died was not running instrumentation,
4917        // then tell everyone we are now low on memory.
4918        boolean haveBg = false;
4919        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4920            ProcessRecord rec = mLruProcesses.get(i);
4921            if (rec.thread != null
4922                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4923                haveBg = true;
4924                break;
4925            }
4926        }
4927
4928        if (!haveBg) {
4929            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4930            if (doReport) {
4931                long now = SystemClock.uptimeMillis();
4932                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4933                    doReport = false;
4934                } else {
4935                    mLastMemUsageReportTime = now;
4936                }
4937            }
4938            final ArrayList<ProcessMemInfo> memInfos
4939                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4940            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4941            long now = SystemClock.uptimeMillis();
4942            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4943                ProcessRecord rec = mLruProcesses.get(i);
4944                if (rec == dyingProc || rec.thread == null) {
4945                    continue;
4946                }
4947                if (doReport) {
4948                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4949                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4950                }
4951                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4952                    // The low memory report is overriding any current
4953                    // state for a GC request.  Make sure to do
4954                    // heavy/important/visible/foreground processes first.
4955                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4956                        rec.lastRequestedGc = 0;
4957                    } else {
4958                        rec.lastRequestedGc = rec.lastLowMemory;
4959                    }
4960                    rec.reportLowMemory = true;
4961                    rec.lastLowMemory = now;
4962                    mProcessesToGc.remove(rec);
4963                    addProcessToGcListLocked(rec);
4964                }
4965            }
4966            if (doReport) {
4967                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4968                mHandler.sendMessage(msg);
4969            }
4970            scheduleAppGcsLocked();
4971        }
4972    }
4973
4974    final void appDiedLocked(ProcessRecord app) {
4975       appDiedLocked(app, app.pid, app.thread, false);
4976    }
4977
4978    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4979            boolean fromBinderDied) {
4980        // First check if this ProcessRecord is actually active for the pid.
4981        synchronized (mPidsSelfLocked) {
4982            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4983            if (curProc != app) {
4984                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4985                return;
4986            }
4987        }
4988
4989        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4990        synchronized (stats) {
4991            stats.noteProcessDiedLocked(app.info.uid, pid);
4992        }
4993
4994        if (!app.killed) {
4995            if (!fromBinderDied) {
4996                Process.killProcessQuiet(pid);
4997            }
4998            killProcessGroup(app.info.uid, pid);
4999            app.killed = true;
5000        }
5001
5002        // Clean up already done if the process has been re-started.
5003        if (app.pid == pid && app.thread != null &&
5004                app.thread.asBinder() == thread.asBinder()) {
5005            boolean doLowMem = app.instrumentationClass == null;
5006            boolean doOomAdj = doLowMem;
5007            if (!app.killedByAm) {
5008                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5009                        + ") has died");
5010                mAllowLowerMemLevel = true;
5011            } else {
5012                // Note that we always want to do oom adj to update our state with the
5013                // new number of procs.
5014                mAllowLowerMemLevel = false;
5015                doLowMem = false;
5016            }
5017            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5018            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5019                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5020            handleAppDiedLocked(app, false, true);
5021
5022            if (doOomAdj) {
5023                updateOomAdjLocked();
5024            }
5025            if (doLowMem) {
5026                doLowMemReportIfNeededLocked(app);
5027            }
5028        } else if (app.pid != pid) {
5029            // A new process has already been started.
5030            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5031                    + ") has died and restarted (pid " + app.pid + ").");
5032            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5033        } else if (DEBUG_PROCESSES) {
5034            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5035                    + thread.asBinder());
5036        }
5037    }
5038
5039    /**
5040     * If a stack trace dump file is configured, dump process stack traces.
5041     * @param clearTraces causes the dump file to be erased prior to the new
5042     *    traces being written, if true; when false, the new traces will be
5043     *    appended to any existing file content.
5044     * @param firstPids of dalvik VM processes to dump stack traces for first
5045     * @param lastPids of dalvik VM processes to dump stack traces for last
5046     * @param nativeProcs optional list of native process names to dump stack crawls
5047     * @return file containing stack traces, or null if no dump file is configured
5048     */
5049    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5050            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5051        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5052        if (tracesPath == null || tracesPath.length() == 0) {
5053            return null;
5054        }
5055
5056        File tracesFile = new File(tracesPath);
5057        try {
5058            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5059            tracesFile.createNewFile();
5060            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5061        } catch (IOException e) {
5062            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5063            return null;
5064        }
5065
5066        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5067        return tracesFile;
5068    }
5069
5070    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5071            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5072        // Use a FileObserver to detect when traces finish writing.
5073        // The order of traces is considered important to maintain for legibility.
5074        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5075            @Override
5076            public synchronized void onEvent(int event, String path) { notify(); }
5077        };
5078
5079        try {
5080            observer.startWatching();
5081
5082            // First collect all of the stacks of the most important pids.
5083            if (firstPids != null) {
5084                try {
5085                    int num = firstPids.size();
5086                    for (int i = 0; i < num; i++) {
5087                        synchronized (observer) {
5088                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5089                            observer.wait(200);  // Wait for write-close, give up after 200msec
5090                        }
5091                    }
5092                } catch (InterruptedException e) {
5093                    Slog.wtf(TAG, e);
5094                }
5095            }
5096
5097            // Next collect the stacks of the native pids
5098            if (nativeProcs != null) {
5099                int[] pids = Process.getPidsForCommands(nativeProcs);
5100                if (pids != null) {
5101                    for (int pid : pids) {
5102                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5103                    }
5104                }
5105            }
5106
5107            // Lastly, measure CPU usage.
5108            if (processCpuTracker != null) {
5109                processCpuTracker.init();
5110                System.gc();
5111                processCpuTracker.update();
5112                try {
5113                    synchronized (processCpuTracker) {
5114                        processCpuTracker.wait(500); // measure over 1/2 second.
5115                    }
5116                } catch (InterruptedException e) {
5117                }
5118                processCpuTracker.update();
5119
5120                // We'll take the stack crawls of just the top apps using CPU.
5121                final int N = processCpuTracker.countWorkingStats();
5122                int numProcs = 0;
5123                for (int i=0; i<N && numProcs<5; i++) {
5124                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5125                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5126                        numProcs++;
5127                        try {
5128                            synchronized (observer) {
5129                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5130                                observer.wait(200);  // Wait for write-close, give up after 200msec
5131                            }
5132                        } catch (InterruptedException e) {
5133                            Slog.wtf(TAG, e);
5134                        }
5135
5136                    }
5137                }
5138            }
5139        } finally {
5140            observer.stopWatching();
5141        }
5142    }
5143
5144    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5145        if (true || IS_USER_BUILD) {
5146            return;
5147        }
5148        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5149        if (tracesPath == null || tracesPath.length() == 0) {
5150            return;
5151        }
5152
5153        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5154        StrictMode.allowThreadDiskWrites();
5155        try {
5156            final File tracesFile = new File(tracesPath);
5157            final File tracesDir = tracesFile.getParentFile();
5158            final File tracesTmp = new File(tracesDir, "__tmp__");
5159            try {
5160                if (tracesFile.exists()) {
5161                    tracesTmp.delete();
5162                    tracesFile.renameTo(tracesTmp);
5163                }
5164                StringBuilder sb = new StringBuilder();
5165                Time tobj = new Time();
5166                tobj.set(System.currentTimeMillis());
5167                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5168                sb.append(": ");
5169                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5170                sb.append(" since ");
5171                sb.append(msg);
5172                FileOutputStream fos = new FileOutputStream(tracesFile);
5173                fos.write(sb.toString().getBytes());
5174                if (app == null) {
5175                    fos.write("\n*** No application process!".getBytes());
5176                }
5177                fos.close();
5178                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5179            } catch (IOException e) {
5180                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5181                return;
5182            }
5183
5184            if (app != null) {
5185                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5186                firstPids.add(app.pid);
5187                dumpStackTraces(tracesPath, firstPids, null, null, null);
5188            }
5189
5190            File lastTracesFile = null;
5191            File curTracesFile = null;
5192            for (int i=9; i>=0; i--) {
5193                String name = String.format(Locale.US, "slow%02d.txt", i);
5194                curTracesFile = new File(tracesDir, name);
5195                if (curTracesFile.exists()) {
5196                    if (lastTracesFile != null) {
5197                        curTracesFile.renameTo(lastTracesFile);
5198                    } else {
5199                        curTracesFile.delete();
5200                    }
5201                }
5202                lastTracesFile = curTracesFile;
5203            }
5204            tracesFile.renameTo(curTracesFile);
5205            if (tracesTmp.exists()) {
5206                tracesTmp.renameTo(tracesFile);
5207            }
5208        } finally {
5209            StrictMode.setThreadPolicy(oldPolicy);
5210        }
5211    }
5212
5213    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5214        if (!mLaunchWarningShown) {
5215            mLaunchWarningShown = true;
5216            mUiHandler.post(new Runnable() {
5217                @Override
5218                public void run() {
5219                    synchronized (ActivityManagerService.this) {
5220                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5221                        d.show();
5222                        mUiHandler.postDelayed(new Runnable() {
5223                            @Override
5224                            public void run() {
5225                                synchronized (ActivityManagerService.this) {
5226                                    d.dismiss();
5227                                    mLaunchWarningShown = false;
5228                                }
5229                            }
5230                        }, 4000);
5231                    }
5232                }
5233            });
5234        }
5235    }
5236
5237    @Override
5238    public boolean clearApplicationUserData(final String packageName,
5239            final IPackageDataObserver observer, int userId) {
5240        enforceNotIsolatedCaller("clearApplicationUserData");
5241        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5242            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5243        }
5244        int uid = Binder.getCallingUid();
5245        int pid = Binder.getCallingPid();
5246        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5247                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5248        long callingId = Binder.clearCallingIdentity();
5249        try {
5250            IPackageManager pm = AppGlobals.getPackageManager();
5251            int pkgUid = -1;
5252            synchronized(this) {
5253                try {
5254                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5255                } catch (RemoteException e) {
5256                }
5257                if (pkgUid == -1) {
5258                    Slog.w(TAG, "Invalid packageName: " + packageName);
5259                    if (observer != null) {
5260                        try {
5261                            observer.onRemoveCompleted(packageName, false);
5262                        } catch (RemoteException e) {
5263                            Slog.i(TAG, "Observer no longer exists.");
5264                        }
5265                    }
5266                    return false;
5267                }
5268                if (uid == pkgUid || checkComponentPermission(
5269                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5270                        pid, uid, -1, true)
5271                        == PackageManager.PERMISSION_GRANTED) {
5272                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5273                } else {
5274                    throw new SecurityException("PID " + pid + " does not have permission "
5275                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5276                                    + " of package " + packageName);
5277                }
5278
5279                // Remove all tasks match the cleared application package and user
5280                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5281                    final TaskRecord tr = mRecentTasks.get(i);
5282                    final String taskPackageName =
5283                            tr.getBaseIntent().getComponent().getPackageName();
5284                    if (tr.userId != userId) continue;
5285                    if (!taskPackageName.equals(packageName)) continue;
5286                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5287                }
5288            }
5289
5290            try {
5291                // Clear application user data
5292                pm.clearApplicationUserData(packageName, observer, userId);
5293
5294                synchronized(this) {
5295                    // Remove all permissions granted from/to this package
5296                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5297                }
5298
5299                // Remove all zen rules created by this package; revoke it's zen access.
5300                INotificationManager inm = NotificationManager.getService();
5301                inm.removeAutomaticZenRules(packageName);
5302                inm.setNotificationPolicyAccessGranted(packageName, false);
5303
5304                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5305                        Uri.fromParts("package", packageName, null));
5306                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5307                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5308                        null, null, 0, null, null, null, null, false, false, userId);
5309            } catch (RemoteException e) {
5310            }
5311        } finally {
5312            Binder.restoreCallingIdentity(callingId);
5313        }
5314        return true;
5315    }
5316
5317    @Override
5318    public void killBackgroundProcesses(final String packageName, int userId) {
5319        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5320                != PackageManager.PERMISSION_GRANTED &&
5321                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5322                        != PackageManager.PERMISSION_GRANTED) {
5323            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5324                    + Binder.getCallingPid()
5325                    + ", uid=" + Binder.getCallingUid()
5326                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5327            Slog.w(TAG, msg);
5328            throw new SecurityException(msg);
5329        }
5330
5331        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5332                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5333        long callingId = Binder.clearCallingIdentity();
5334        try {
5335            IPackageManager pm = AppGlobals.getPackageManager();
5336            synchronized(this) {
5337                int appId = -1;
5338                try {
5339                    appId = UserHandle.getAppId(
5340                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5341                } catch (RemoteException e) {
5342                }
5343                if (appId == -1) {
5344                    Slog.w(TAG, "Invalid packageName: " + packageName);
5345                    return;
5346                }
5347                killPackageProcessesLocked(packageName, appId, userId,
5348                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5349            }
5350        } finally {
5351            Binder.restoreCallingIdentity(callingId);
5352        }
5353    }
5354
5355    @Override
5356    public void killAllBackgroundProcesses() {
5357        killAllBackgroundProcesses(-1);
5358    }
5359
5360    /**
5361     * Kills all background processes with targetSdkVersion below the specified
5362     * target SDK version.
5363     *
5364     * @param targetSdkVersion the target SDK version below which to kill
5365     *                         processes, or {@code -1} to kill all processes
5366     */
5367    private void killAllBackgroundProcesses(int targetSdkVersion) {
5368        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5369                != PackageManager.PERMISSION_GRANTED) {
5370            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5371                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5372                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5373            Slog.w(TAG, msg);
5374            throw new SecurityException(msg);
5375        }
5376
5377        final long callingId = Binder.clearCallingIdentity();
5378        try {
5379            synchronized (this) {
5380                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5381                final int NP = mProcessNames.getMap().size();
5382                for (int ip = 0; ip < NP; ip++) {
5383                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5384                    final int NA = apps.size();
5385                    for (int ia = 0; ia < NA; ia++) {
5386                        final ProcessRecord app = apps.valueAt(ia);
5387                        if (app.persistent) {
5388                            // We don't kill persistent processes.
5389                            continue;
5390                        }
5391                        if (targetSdkVersion > 0
5392                                && app.info.targetSdkVersion >= targetSdkVersion) {
5393                            continue;
5394                        }
5395                        if (app.removed) {
5396                            procs.add(app);
5397                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5398                            app.removed = true;
5399                            procs.add(app);
5400                        }
5401                    }
5402                }
5403
5404                final int N = procs.size();
5405                for (int i = 0; i < N; i++) {
5406                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5407                }
5408
5409                mAllowLowerMemLevel = true;
5410
5411                updateOomAdjLocked();
5412                doLowMemReportIfNeededLocked(null);
5413            }
5414        } finally {
5415            Binder.restoreCallingIdentity(callingId);
5416        }
5417    }
5418
5419    @Override
5420    public void forceStopPackage(final String packageName, int userId) {
5421        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5422                != PackageManager.PERMISSION_GRANTED) {
5423            String msg = "Permission Denial: forceStopPackage() from pid="
5424                    + Binder.getCallingPid()
5425                    + ", uid=" + Binder.getCallingUid()
5426                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5427            Slog.w(TAG, msg);
5428            throw new SecurityException(msg);
5429        }
5430        final int callingPid = Binder.getCallingPid();
5431        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5432                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5433        long callingId = Binder.clearCallingIdentity();
5434        try {
5435            IPackageManager pm = AppGlobals.getPackageManager();
5436            synchronized(this) {
5437                int[] users = userId == UserHandle.USER_ALL
5438                        ? mUserController.getUsers() : new int[] { userId };
5439                for (int user : users) {
5440                    int pkgUid = -1;
5441                    try {
5442                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5443                                user);
5444                    } catch (RemoteException e) {
5445                    }
5446                    if (pkgUid == -1) {
5447                        Slog.w(TAG, "Invalid packageName: " + packageName);
5448                        continue;
5449                    }
5450                    try {
5451                        pm.setPackageStoppedState(packageName, true, user);
5452                    } catch (RemoteException e) {
5453                    } catch (IllegalArgumentException e) {
5454                        Slog.w(TAG, "Failed trying to unstop package "
5455                                + packageName + ": " + e);
5456                    }
5457                    if (mUserController.isUserRunningLocked(user, 0)) {
5458                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5459                    }
5460                }
5461            }
5462        } finally {
5463            Binder.restoreCallingIdentity(callingId);
5464        }
5465    }
5466
5467    @Override
5468    public void addPackageDependency(String packageName) {
5469        synchronized (this) {
5470            int callingPid = Binder.getCallingPid();
5471            if (callingPid == Process.myPid()) {
5472                //  Yeah, um, no.
5473                return;
5474            }
5475            ProcessRecord proc;
5476            synchronized (mPidsSelfLocked) {
5477                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5478            }
5479            if (proc != null) {
5480                if (proc.pkgDeps == null) {
5481                    proc.pkgDeps = new ArraySet<String>(1);
5482                }
5483                proc.pkgDeps.add(packageName);
5484            }
5485        }
5486    }
5487
5488    /*
5489     * The pkg name and app id have to be specified.
5490     */
5491    @Override
5492    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5493        if (pkg == null) {
5494            return;
5495        }
5496        // Make sure the uid is valid.
5497        if (appid < 0) {
5498            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5499            return;
5500        }
5501        int callerUid = Binder.getCallingUid();
5502        // Only the system server can kill an application
5503        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5504            // Post an aysnc message to kill the application
5505            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5506            msg.arg1 = appid;
5507            msg.arg2 = 0;
5508            Bundle bundle = new Bundle();
5509            bundle.putString("pkg", pkg);
5510            bundle.putString("reason", reason);
5511            msg.obj = bundle;
5512            mHandler.sendMessage(msg);
5513        } else {
5514            throw new SecurityException(callerUid + " cannot kill pkg: " +
5515                    pkg);
5516        }
5517    }
5518
5519    @Override
5520    public void closeSystemDialogs(String reason) {
5521        enforceNotIsolatedCaller("closeSystemDialogs");
5522
5523        final int pid = Binder.getCallingPid();
5524        final int uid = Binder.getCallingUid();
5525        final long origId = Binder.clearCallingIdentity();
5526        try {
5527            synchronized (this) {
5528                // Only allow this from foreground processes, so that background
5529                // applications can't abuse it to prevent system UI from being shown.
5530                if (uid >= Process.FIRST_APPLICATION_UID) {
5531                    ProcessRecord proc;
5532                    synchronized (mPidsSelfLocked) {
5533                        proc = mPidsSelfLocked.get(pid);
5534                    }
5535                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5536                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5537                                + " from background process " + proc);
5538                        return;
5539                    }
5540                }
5541                closeSystemDialogsLocked(reason);
5542            }
5543        } finally {
5544            Binder.restoreCallingIdentity(origId);
5545        }
5546    }
5547
5548    void closeSystemDialogsLocked(String reason) {
5549        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5550        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5551                | Intent.FLAG_RECEIVER_FOREGROUND);
5552        if (reason != null) {
5553            intent.putExtra("reason", reason);
5554        }
5555        mWindowManager.closeSystemDialogs(reason);
5556
5557        mStackSupervisor.closeSystemDialogsLocked();
5558
5559        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5560                AppOpsManager.OP_NONE, null, false, false,
5561                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5562    }
5563
5564    @Override
5565    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5566        enforceNotIsolatedCaller("getProcessMemoryInfo");
5567        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5568        for (int i=pids.length-1; i>=0; i--) {
5569            ProcessRecord proc;
5570            int oomAdj;
5571            synchronized (this) {
5572                synchronized (mPidsSelfLocked) {
5573                    proc = mPidsSelfLocked.get(pids[i]);
5574                    oomAdj = proc != null ? proc.setAdj : 0;
5575                }
5576            }
5577            infos[i] = new Debug.MemoryInfo();
5578            Debug.getMemoryInfo(pids[i], infos[i]);
5579            if (proc != null) {
5580                synchronized (this) {
5581                    if (proc.thread != null && proc.setAdj == oomAdj) {
5582                        // Record this for posterity if the process has been stable.
5583                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5584                                infos[i].getTotalUss(), false, proc.pkgList);
5585                    }
5586                }
5587            }
5588        }
5589        return infos;
5590    }
5591
5592    @Override
5593    public long[] getProcessPss(int[] pids) {
5594        enforceNotIsolatedCaller("getProcessPss");
5595        long[] pss = new long[pids.length];
5596        for (int i=pids.length-1; i>=0; i--) {
5597            ProcessRecord proc;
5598            int oomAdj;
5599            synchronized (this) {
5600                synchronized (mPidsSelfLocked) {
5601                    proc = mPidsSelfLocked.get(pids[i]);
5602                    oomAdj = proc != null ? proc.setAdj : 0;
5603                }
5604            }
5605            long[] tmpUss = new long[1];
5606            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5607            if (proc != null) {
5608                synchronized (this) {
5609                    if (proc.thread != null && proc.setAdj == oomAdj) {
5610                        // Record this for posterity if the process has been stable.
5611                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5612                    }
5613                }
5614            }
5615        }
5616        return pss;
5617    }
5618
5619    @Override
5620    public void killApplicationProcess(String processName, int uid) {
5621        if (processName == null) {
5622            return;
5623        }
5624
5625        int callerUid = Binder.getCallingUid();
5626        // Only the system server can kill an application
5627        if (callerUid == Process.SYSTEM_UID) {
5628            synchronized (this) {
5629                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5630                if (app != null && app.thread != null) {
5631                    try {
5632                        app.thread.scheduleSuicide();
5633                    } catch (RemoteException e) {
5634                        // If the other end already died, then our work here is done.
5635                    }
5636                } else {
5637                    Slog.w(TAG, "Process/uid not found attempting kill of "
5638                            + processName + " / " + uid);
5639                }
5640            }
5641        } else {
5642            throw new SecurityException(callerUid + " cannot kill app process: " +
5643                    processName);
5644        }
5645    }
5646
5647    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5648        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5649                false, true, false, false, UserHandle.getUserId(uid), reason);
5650        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5651                Uri.fromParts("package", packageName, null));
5652        if (!mProcessesReady) {
5653            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5654                    | Intent.FLAG_RECEIVER_FOREGROUND);
5655        }
5656        intent.putExtra(Intent.EXTRA_UID, uid);
5657        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5658        broadcastIntentLocked(null, null, intent,
5659                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5660                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5661    }
5662
5663
5664    private final boolean killPackageProcessesLocked(String packageName, int appId,
5665            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5666            boolean doit, boolean evenPersistent, String reason) {
5667        ArrayList<ProcessRecord> procs = new ArrayList<>();
5668
5669        // Remove all processes this package may have touched: all with the
5670        // same UID (except for the system or root user), and all whose name
5671        // matches the package name.
5672        final int NP = mProcessNames.getMap().size();
5673        for (int ip=0; ip<NP; ip++) {
5674            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5675            final int NA = apps.size();
5676            for (int ia=0; ia<NA; ia++) {
5677                ProcessRecord app = apps.valueAt(ia);
5678                if (app.persistent && !evenPersistent) {
5679                    // we don't kill persistent processes
5680                    continue;
5681                }
5682                if (app.removed) {
5683                    if (doit) {
5684                        procs.add(app);
5685                    }
5686                    continue;
5687                }
5688
5689                // Skip process if it doesn't meet our oom adj requirement.
5690                if (app.setAdj < minOomAdj) {
5691                    continue;
5692                }
5693
5694                // If no package is specified, we call all processes under the
5695                // give user id.
5696                if (packageName == null) {
5697                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5698                        continue;
5699                    }
5700                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5701                        continue;
5702                    }
5703                // Package has been specified, we want to hit all processes
5704                // that match it.  We need to qualify this by the processes
5705                // that are running under the specified app and user ID.
5706                } else {
5707                    final boolean isDep = app.pkgDeps != null
5708                            && app.pkgDeps.contains(packageName);
5709                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5710                        continue;
5711                    }
5712                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5713                        continue;
5714                    }
5715                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5716                        continue;
5717                    }
5718                }
5719
5720                // Process has passed all conditions, kill it!
5721                if (!doit) {
5722                    return true;
5723                }
5724                app.removed = true;
5725                procs.add(app);
5726            }
5727        }
5728
5729        int N = procs.size();
5730        for (int i=0; i<N; i++) {
5731            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5732        }
5733        updateOomAdjLocked();
5734        return N > 0;
5735    }
5736
5737    private void cleanupDisabledPackageComponentsLocked(
5738            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5739
5740        Set<String> disabledClasses = null;
5741        boolean packageDisabled = false;
5742        IPackageManager pm = AppGlobals.getPackageManager();
5743
5744        if (changedClasses == null) {
5745            // Nothing changed...
5746            return;
5747        }
5748
5749        // Determine enable/disable state of the package and its components.
5750        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5751        for (int i = changedClasses.length - 1; i >= 0; i--) {
5752            final String changedClass = changedClasses[i];
5753
5754            if (changedClass.equals(packageName)) {
5755                try {
5756                    // Entire package setting changed
5757                    enabled = pm.getApplicationEnabledSetting(packageName,
5758                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5759                } catch (Exception e) {
5760                    // No such package/component; probably racing with uninstall.  In any
5761                    // event it means we have nothing further to do here.
5762                    return;
5763                }
5764                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5765                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5766                if (packageDisabled) {
5767                    // Entire package is disabled.
5768                    // No need to continue to check component states.
5769                    disabledClasses = null;
5770                    break;
5771                }
5772            } else {
5773                try {
5774                    enabled = pm.getComponentEnabledSetting(
5775                            new ComponentName(packageName, changedClass),
5776                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5777                } catch (Exception e) {
5778                    // As above, probably racing with uninstall.
5779                    return;
5780                }
5781                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5782                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5783                    if (disabledClasses == null) {
5784                        disabledClasses = new ArraySet<>(changedClasses.length);
5785                    }
5786                    disabledClasses.add(changedClass);
5787                }
5788            }
5789        }
5790
5791        if (!packageDisabled && disabledClasses == null) {
5792            // Nothing to do here...
5793            return;
5794        }
5795
5796        // Clean-up disabled activities.
5797        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5798                packageName, disabledClasses, true, false, userId) && mBooted) {
5799            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5800            mStackSupervisor.scheduleIdleLocked();
5801        }
5802
5803        // Clean-up disabled tasks
5804        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5805
5806        // Clean-up disabled services.
5807        mServices.bringDownDisabledPackageServicesLocked(
5808                packageName, disabledClasses, userId, false, killProcess, true);
5809
5810        // Clean-up disabled providers.
5811        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5812        mProviderMap.collectPackageProvidersLocked(
5813                packageName, disabledClasses, true, false, userId, providers);
5814        for (int i = providers.size() - 1; i >= 0; i--) {
5815            removeDyingProviderLocked(null, providers.get(i), true);
5816        }
5817
5818        // Clean-up disabled broadcast receivers.
5819        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5820            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5821                    packageName, disabledClasses, userId, true);
5822        }
5823
5824    }
5825
5826    final boolean forceStopPackageLocked(String packageName, int appId,
5827            boolean callerWillRestart, boolean purgeCache, boolean doit,
5828            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5829        int i;
5830
5831        if (userId == UserHandle.USER_ALL && packageName == null) {
5832            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5833        }
5834
5835        if (appId < 0 && packageName != null) {
5836            try {
5837                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5838                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5839            } catch (RemoteException e) {
5840            }
5841        }
5842
5843        if (doit) {
5844            if (packageName != null) {
5845                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5846                        + " user=" + userId + ": " + reason);
5847            } else {
5848                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5849            }
5850
5851            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5852        }
5853
5854        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5855                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5856                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5857
5858        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5859                packageName, null, doit, evenPersistent, userId)) {
5860            if (!doit) {
5861                return true;
5862            }
5863            didSomething = true;
5864        }
5865
5866        if (mServices.bringDownDisabledPackageServicesLocked(
5867                packageName, null, userId, evenPersistent, true, doit)) {
5868            if (!doit) {
5869                return true;
5870            }
5871            didSomething = true;
5872        }
5873
5874        if (packageName == null) {
5875            // Remove all sticky broadcasts from this user.
5876            mStickyBroadcasts.remove(userId);
5877        }
5878
5879        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5880        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5881                userId, providers)) {
5882            if (!doit) {
5883                return true;
5884            }
5885            didSomething = true;
5886        }
5887        for (i = providers.size() - 1; i >= 0; i--) {
5888            removeDyingProviderLocked(null, providers.get(i), true);
5889        }
5890
5891        // Remove transient permissions granted from/to this package/user
5892        removeUriPermissionsForPackageLocked(packageName, userId, false);
5893
5894        if (doit) {
5895            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5896                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5897                        packageName, null, userId, doit);
5898            }
5899        }
5900
5901        if (packageName == null || uninstalling) {
5902            // Remove pending intents.  For now we only do this when force
5903            // stopping users, because we have some problems when doing this
5904            // for packages -- app widgets are not currently cleaned up for
5905            // such packages, so they can be left with bad pending intents.
5906            if (mIntentSenderRecords.size() > 0) {
5907                Iterator<WeakReference<PendingIntentRecord>> it
5908                        = mIntentSenderRecords.values().iterator();
5909                while (it.hasNext()) {
5910                    WeakReference<PendingIntentRecord> wpir = it.next();
5911                    if (wpir == null) {
5912                        it.remove();
5913                        continue;
5914                    }
5915                    PendingIntentRecord pir = wpir.get();
5916                    if (pir == null) {
5917                        it.remove();
5918                        continue;
5919                    }
5920                    if (packageName == null) {
5921                        // Stopping user, remove all objects for the user.
5922                        if (pir.key.userId != userId) {
5923                            // Not the same user, skip it.
5924                            continue;
5925                        }
5926                    } else {
5927                        if (UserHandle.getAppId(pir.uid) != appId) {
5928                            // Different app id, skip it.
5929                            continue;
5930                        }
5931                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5932                            // Different user, skip it.
5933                            continue;
5934                        }
5935                        if (!pir.key.packageName.equals(packageName)) {
5936                            // Different package, skip it.
5937                            continue;
5938                        }
5939                    }
5940                    if (!doit) {
5941                        return true;
5942                    }
5943                    didSomething = true;
5944                    it.remove();
5945                    pir.canceled = true;
5946                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5947                        pir.key.activity.pendingResults.remove(pir.ref);
5948                    }
5949                }
5950            }
5951        }
5952
5953        if (doit) {
5954            if (purgeCache && packageName != null) {
5955                AttributeCache ac = AttributeCache.instance();
5956                if (ac != null) {
5957                    ac.removePackage(packageName);
5958                }
5959            }
5960            if (mBooted) {
5961                mStackSupervisor.resumeFocusedStackTopActivityLocked();
5962                mStackSupervisor.scheduleIdleLocked();
5963            }
5964        }
5965
5966        return didSomething;
5967    }
5968
5969    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5970        ProcessRecord old = mProcessNames.remove(name, uid);
5971        if (old != null) {
5972            old.uidRecord.numProcs--;
5973            if (old.uidRecord.numProcs == 0) {
5974                // No more processes using this uid, tell clients it is gone.
5975                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5976                        "No more processes in " + old.uidRecord);
5977                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
5978                mActiveUids.remove(uid);
5979                mBatteryStatsService.noteUidProcessState(uid,
5980                        ActivityManager.PROCESS_STATE_NONEXISTENT);
5981            }
5982            old.uidRecord = null;
5983        }
5984        mIsolatedProcesses.remove(uid);
5985        return old;
5986    }
5987
5988    private final void addProcessNameLocked(ProcessRecord proc) {
5989        // We shouldn't already have a process under this name, but just in case we
5990        // need to clean up whatever may be there now.
5991        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5992        if (old == proc && proc.persistent) {
5993            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5994            Slog.w(TAG, "Re-adding persistent process " + proc);
5995        } else if (old != null) {
5996            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5997        }
5998        UidRecord uidRec = mActiveUids.get(proc.uid);
5999        if (uidRec == null) {
6000            uidRec = new UidRecord(proc.uid);
6001            // This is the first appearance of the uid, report it now!
6002            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6003                    "Creating new process uid: " + uidRec);
6004            mActiveUids.put(proc.uid, uidRec);
6005            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6006            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6007        }
6008        proc.uidRecord = uidRec;
6009        uidRec.numProcs++;
6010        mProcessNames.put(proc.processName, proc.uid, proc);
6011        if (proc.isolated) {
6012            mIsolatedProcesses.put(proc.uid, proc);
6013        }
6014    }
6015
6016    boolean removeProcessLocked(ProcessRecord app,
6017            boolean callerWillRestart, boolean allowRestart, String reason) {
6018        final String name = app.processName;
6019        final int uid = app.uid;
6020        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6021            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6022
6023        removeProcessNameLocked(name, uid);
6024        if (mHeavyWeightProcess == app) {
6025            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6026                    mHeavyWeightProcess.userId, 0));
6027            mHeavyWeightProcess = null;
6028        }
6029        boolean needRestart = false;
6030        if (app.pid > 0 && app.pid != MY_PID) {
6031            int pid = app.pid;
6032            synchronized (mPidsSelfLocked) {
6033                mPidsSelfLocked.remove(pid);
6034                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6035            }
6036            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6037            if (app.isolated) {
6038                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6039            }
6040            boolean willRestart = false;
6041            if (app.persistent && !app.isolated) {
6042                if (!callerWillRestart) {
6043                    willRestart = true;
6044                } else {
6045                    needRestart = true;
6046                }
6047            }
6048            app.kill(reason, true);
6049            handleAppDiedLocked(app, willRestart, allowRestart);
6050            if (willRestart) {
6051                removeLruProcessLocked(app);
6052                addAppLocked(app.info, false, null /* ABI override */);
6053            }
6054        } else {
6055            mRemovedProcesses.add(app);
6056        }
6057
6058        return needRestart;
6059    }
6060
6061    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6062        cleanupAppInLaunchingProvidersLocked(app, true);
6063        removeProcessLocked(app, false, true, "timeout publishing content providers");
6064    }
6065
6066    private final void processStartTimedOutLocked(ProcessRecord app) {
6067        final int pid = app.pid;
6068        boolean gone = false;
6069        synchronized (mPidsSelfLocked) {
6070            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6071            if (knownApp != null && knownApp.thread == null) {
6072                mPidsSelfLocked.remove(pid);
6073                gone = true;
6074            }
6075        }
6076
6077        if (gone) {
6078            Slog.w(TAG, "Process " + app + " failed to attach");
6079            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6080                    pid, app.uid, app.processName);
6081            removeProcessNameLocked(app.processName, app.uid);
6082            if (mHeavyWeightProcess == app) {
6083                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6084                        mHeavyWeightProcess.userId, 0));
6085                mHeavyWeightProcess = null;
6086            }
6087            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6088            if (app.isolated) {
6089                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6090            }
6091            // Take care of any launching providers waiting for this process.
6092            cleanupAppInLaunchingProvidersLocked(app, true);
6093            // Take care of any services that are waiting for the process.
6094            mServices.processStartTimedOutLocked(app);
6095            app.kill("start timeout", true);
6096            removeLruProcessLocked(app);
6097            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6098                Slog.w(TAG, "Unattached app died before backup, skipping");
6099                try {
6100                    IBackupManager bm = IBackupManager.Stub.asInterface(
6101                            ServiceManager.getService(Context.BACKUP_SERVICE));
6102                    bm.agentDisconnected(app.info.packageName);
6103                } catch (RemoteException e) {
6104                    // Can't happen; the backup manager is local
6105                }
6106            }
6107            if (isPendingBroadcastProcessLocked(pid)) {
6108                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6109                skipPendingBroadcastLocked(pid);
6110            }
6111        } else {
6112            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6113        }
6114    }
6115
6116    private final boolean attachApplicationLocked(IApplicationThread thread,
6117            int pid) {
6118
6119        // Find the application record that is being attached...  either via
6120        // the pid if we are running in multiple processes, or just pull the
6121        // next app record if we are emulating process with anonymous threads.
6122        ProcessRecord app;
6123        if (pid != MY_PID && pid >= 0) {
6124            synchronized (mPidsSelfLocked) {
6125                app = mPidsSelfLocked.get(pid);
6126            }
6127        } else {
6128            app = null;
6129        }
6130
6131        if (app == null) {
6132            Slog.w(TAG, "No pending application record for pid " + pid
6133                    + " (IApplicationThread " + thread + "); dropping process");
6134            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6135            if (pid > 0 && pid != MY_PID) {
6136                Process.killProcessQuiet(pid);
6137                //TODO: killProcessGroup(app.info.uid, pid);
6138            } else {
6139                try {
6140                    thread.scheduleExit();
6141                } catch (Exception e) {
6142                    // Ignore exceptions.
6143                }
6144            }
6145            return false;
6146        }
6147
6148        // If this application record is still attached to a previous
6149        // process, clean it up now.
6150        if (app.thread != null) {
6151            handleAppDiedLocked(app, true, true);
6152        }
6153
6154        // Tell the process all about itself.
6155
6156        if (DEBUG_ALL) Slog.v(
6157                TAG, "Binding process pid " + pid + " to record " + app);
6158
6159        final String processName = app.processName;
6160        try {
6161            AppDeathRecipient adr = new AppDeathRecipient(
6162                    app, pid, thread);
6163            thread.asBinder().linkToDeath(adr, 0);
6164            app.deathRecipient = adr;
6165        } catch (RemoteException e) {
6166            app.resetPackageList(mProcessStats);
6167            startProcessLocked(app, "link fail", processName);
6168            return false;
6169        }
6170
6171        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6172
6173        app.makeActive(thread, mProcessStats);
6174        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6175        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6176        app.forcingToForeground = null;
6177        updateProcessForegroundLocked(app, false, false);
6178        app.hasShownUi = false;
6179        app.debugging = false;
6180        app.cached = false;
6181        app.killedByAm = false;
6182
6183        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6184
6185        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6186        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6187
6188        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6189            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6190            msg.obj = app;
6191            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6192        }
6193
6194        if (!normalMode) {
6195            Slog.i(TAG, "Launching preboot mode app: " + app);
6196        }
6197
6198        if (DEBUG_ALL) Slog.v(
6199            TAG, "New app record " + app
6200            + " thread=" + thread.asBinder() + " pid=" + pid);
6201        try {
6202            int testMode = IApplicationThread.DEBUG_OFF;
6203            if (mDebugApp != null && mDebugApp.equals(processName)) {
6204                testMode = mWaitForDebugger
6205                    ? IApplicationThread.DEBUG_WAIT
6206                    : IApplicationThread.DEBUG_ON;
6207                app.debugging = true;
6208                if (mDebugTransient) {
6209                    mDebugApp = mOrigDebugApp;
6210                    mWaitForDebugger = mOrigWaitForDebugger;
6211                }
6212            }
6213            String profileFile = app.instrumentationProfileFile;
6214            ParcelFileDescriptor profileFd = null;
6215            int samplingInterval = 0;
6216            boolean profileAutoStop = false;
6217            if (mProfileApp != null && mProfileApp.equals(processName)) {
6218                mProfileProc = app;
6219                profileFile = mProfileFile;
6220                profileFd = mProfileFd;
6221                samplingInterval = mSamplingInterval;
6222                profileAutoStop = mAutoStopProfiler;
6223            }
6224            boolean enableTrackAllocation = false;
6225            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6226                enableTrackAllocation = true;
6227                mTrackAllocationApp = null;
6228            }
6229
6230            // If the app is being launched for restore or full backup, set it up specially
6231            boolean isRestrictedBackupMode = false;
6232            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6233                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6234                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6235                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6236            }
6237
6238            notifyPackageUse(app.instrumentationInfo != null
6239                    ? app.instrumentationInfo.packageName
6240                    : app.info.packageName);
6241            if (app.instrumentationClass != null) {
6242                notifyPackageUse(app.instrumentationClass.getPackageName());
6243            }
6244            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6245                    + processName + " with config " + mConfiguration);
6246            ApplicationInfo appInfo = app.instrumentationInfo != null
6247                    ? app.instrumentationInfo : app.info;
6248            app.compat = compatibilityInfoForPackageLocked(appInfo);
6249            if (profileFd != null) {
6250                profileFd = profileFd.dup();
6251            }
6252            ProfilerInfo profilerInfo = profileFile == null ? null
6253                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6254            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6255                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6256                    app.instrumentationUiAutomationConnection, testMode,
6257                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6258                    isRestrictedBackupMode || !normalMode, app.persistent,
6259                    new Configuration(mConfiguration), app.compat,
6260                    getCommonServicesLocked(app.isolated),
6261                    mCoreSettingsObserver.getCoreSettingsLocked());
6262            updateLruProcessLocked(app, false, null);
6263            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6264        } catch (Exception e) {
6265            // todo: Yikes!  What should we do?  For now we will try to
6266            // start another process, but that could easily get us in
6267            // an infinite loop of restarting processes...
6268            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6269
6270            app.resetPackageList(mProcessStats);
6271            app.unlinkDeathRecipient();
6272            startProcessLocked(app, "bind fail", processName);
6273            return false;
6274        }
6275
6276        // Remove this record from the list of starting applications.
6277        mPersistentStartingProcesses.remove(app);
6278        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6279                "Attach application locked removing on hold: " + app);
6280        mProcessesOnHold.remove(app);
6281
6282        boolean badApp = false;
6283        boolean didSomething = false;
6284
6285        // See if the top visible activity is waiting to run in this process...
6286        if (normalMode) {
6287            try {
6288                if (mStackSupervisor.attachApplicationLocked(app)) {
6289                    didSomething = true;
6290                }
6291            } catch (Exception e) {
6292                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6293                badApp = true;
6294            }
6295        }
6296
6297        // Find any services that should be running in this process...
6298        if (!badApp) {
6299            try {
6300                didSomething |= mServices.attachApplicationLocked(app, processName);
6301            } catch (Exception e) {
6302                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6303                badApp = true;
6304            }
6305        }
6306
6307        // Check if a next-broadcast receiver is in this process...
6308        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6309            try {
6310                didSomething |= sendPendingBroadcastsLocked(app);
6311            } catch (Exception e) {
6312                // If the app died trying to launch the receiver we declare it 'bad'
6313                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6314                badApp = true;
6315            }
6316        }
6317
6318        // Check whether the next backup agent is in this process...
6319        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6320            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6321                    "New app is backup target, launching agent for " + app);
6322            notifyPackageUse(mBackupTarget.appInfo.packageName);
6323            try {
6324                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6325                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6326                        mBackupTarget.backupMode);
6327            } catch (Exception e) {
6328                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6329                badApp = true;
6330            }
6331        }
6332
6333        if (badApp) {
6334            app.kill("error during init", true);
6335            handleAppDiedLocked(app, false, true);
6336            return false;
6337        }
6338
6339        if (!didSomething) {
6340            updateOomAdjLocked();
6341        }
6342
6343        return true;
6344    }
6345
6346    @Override
6347    public final void attachApplication(IApplicationThread thread) {
6348        synchronized (this) {
6349            int callingPid = Binder.getCallingPid();
6350            final long origId = Binder.clearCallingIdentity();
6351            attachApplicationLocked(thread, callingPid);
6352            Binder.restoreCallingIdentity(origId);
6353        }
6354    }
6355
6356    @Override
6357    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6358        final long origId = Binder.clearCallingIdentity();
6359        synchronized (this) {
6360            ActivityStack stack = ActivityRecord.getStackLocked(token);
6361            if (stack != null) {
6362                ActivityRecord r =
6363                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6364                if (stopProfiling) {
6365                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6366                        try {
6367                            mProfileFd.close();
6368                        } catch (IOException e) {
6369                        }
6370                        clearProfilerLocked();
6371                    }
6372                }
6373            }
6374        }
6375        Binder.restoreCallingIdentity(origId);
6376    }
6377
6378    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6379        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6380                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6381    }
6382
6383    void enableScreenAfterBoot() {
6384        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6385                SystemClock.uptimeMillis());
6386        mWindowManager.enableScreenAfterBoot();
6387
6388        synchronized (this) {
6389            updateEventDispatchingLocked();
6390        }
6391    }
6392
6393    @Override
6394    public void showBootMessage(final CharSequence msg, final boolean always) {
6395        if (Binder.getCallingUid() != Process.myUid()) {
6396            // These days only the core system can call this, so apps can't get in
6397            // the way of what we show about running them.
6398        }
6399        mWindowManager.showBootMessage(msg, always);
6400    }
6401
6402    @Override
6403    public void keyguardWaitingForActivityDrawn() {
6404        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6405        final long token = Binder.clearCallingIdentity();
6406        try {
6407            synchronized (this) {
6408                if (DEBUG_LOCKSCREEN) logLockScreen("");
6409                mWindowManager.keyguardWaitingForActivityDrawn();
6410                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6411                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6412                    updateSleepIfNeededLocked();
6413                }
6414            }
6415        } finally {
6416            Binder.restoreCallingIdentity(token);
6417        }
6418    }
6419
6420    @Override
6421    public void keyguardGoingAway(boolean disableWindowAnimations,
6422            boolean keyguardGoingToNotificationShade) {
6423        enforceNotIsolatedCaller("keyguardGoingAway");
6424        final long token = Binder.clearCallingIdentity();
6425        try {
6426            synchronized (this) {
6427                if (DEBUG_LOCKSCREEN) logLockScreen("");
6428                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6429                        keyguardGoingToNotificationShade);
6430                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6431                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6432                    updateSleepIfNeededLocked();
6433
6434                    // Some stack visibility might change (e.g. docked stack)
6435                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6436                }
6437            }
6438        } finally {
6439            Binder.restoreCallingIdentity(token);
6440        }
6441    }
6442
6443    final void finishBooting() {
6444        synchronized (this) {
6445            if (!mBootAnimationComplete) {
6446                mCallFinishBooting = true;
6447                return;
6448            }
6449            mCallFinishBooting = false;
6450        }
6451
6452        ArraySet<String> completedIsas = new ArraySet<String>();
6453        for (String abi : Build.SUPPORTED_ABIS) {
6454            Process.establishZygoteConnectionForAbi(abi);
6455            final String instructionSet = VMRuntime.getInstructionSet(abi);
6456            if (!completedIsas.contains(instructionSet)) {
6457                try {
6458                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6459                } catch (InstallerException e) {
6460                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6461                }
6462                completedIsas.add(instructionSet);
6463            }
6464        }
6465
6466        IntentFilter pkgFilter = new IntentFilter();
6467        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6468        pkgFilter.addDataScheme("package");
6469        mContext.registerReceiver(new BroadcastReceiver() {
6470            @Override
6471            public void onReceive(Context context, Intent intent) {
6472                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6473                if (pkgs != null) {
6474                    for (String pkg : pkgs) {
6475                        synchronized (ActivityManagerService.this) {
6476                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6477                                    0, "query restart")) {
6478                                setResultCode(Activity.RESULT_OK);
6479                                return;
6480                            }
6481                        }
6482                    }
6483                }
6484            }
6485        }, pkgFilter);
6486
6487        IntentFilter dumpheapFilter = new IntentFilter();
6488        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6489        mContext.registerReceiver(new BroadcastReceiver() {
6490            @Override
6491            public void onReceive(Context context, Intent intent) {
6492                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6493                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6494                } else {
6495                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6496                }
6497            }
6498        }, dumpheapFilter);
6499
6500        mProcessStartLogger.registerListener(mContext);
6501
6502        // Let system services know.
6503        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6504
6505        synchronized (this) {
6506            // Ensure that any processes we had put on hold are now started
6507            // up.
6508            final int NP = mProcessesOnHold.size();
6509            if (NP > 0) {
6510                ArrayList<ProcessRecord> procs =
6511                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6512                for (int ip=0; ip<NP; ip++) {
6513                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6514                            + procs.get(ip));
6515                    startProcessLocked(procs.get(ip), "on-hold", null);
6516                }
6517            }
6518
6519            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6520                // Start looking for apps that are abusing wake locks.
6521                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6522                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6523                // Tell anyone interested that we are done booting!
6524                SystemProperties.set("sys.boot_completed", "1");
6525
6526                // And trigger dev.bootcomplete if we are not showing encryption progress
6527                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6528                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6529                    SystemProperties.set("dev.bootcomplete", "1");
6530                }
6531                mUserController.sendBootCompletedLocked(
6532                        new IIntentReceiver.Stub() {
6533                            @Override
6534                            public void performReceive(Intent intent, int resultCode,
6535                                    String data, Bundle extras, boolean ordered,
6536                                    boolean sticky, int sendingUser) {
6537                                synchronized (ActivityManagerService.this) {
6538                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6539                                            true, false);
6540                                }
6541                            }
6542                        });
6543                scheduleStartProfilesLocked();
6544            }
6545        }
6546    }
6547
6548    @Override
6549    public void bootAnimationComplete() {
6550        final boolean callFinishBooting;
6551        synchronized (this) {
6552            callFinishBooting = mCallFinishBooting;
6553            mBootAnimationComplete = true;
6554        }
6555        if (callFinishBooting) {
6556            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6557            finishBooting();
6558            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6559        }
6560    }
6561
6562    final void ensureBootCompleted() {
6563        boolean booting;
6564        boolean enableScreen;
6565        synchronized (this) {
6566            booting = mBooting;
6567            mBooting = false;
6568            enableScreen = !mBooted;
6569            mBooted = true;
6570        }
6571
6572        if (booting) {
6573            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6574            finishBooting();
6575            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6576        }
6577
6578        if (enableScreen) {
6579            enableScreenAfterBoot();
6580        }
6581    }
6582
6583    @Override
6584    public final void activityResumed(IBinder token) {
6585        final long origId = Binder.clearCallingIdentity();
6586        synchronized(this) {
6587            ActivityStack stack = ActivityRecord.getStackLocked(token);
6588            if (stack != null) {
6589                ActivityRecord.activityResumedLocked(token);
6590            }
6591        }
6592        Binder.restoreCallingIdentity(origId);
6593    }
6594
6595    @Override
6596    public final void activityPaused(IBinder token) {
6597        final long origId = Binder.clearCallingIdentity();
6598        synchronized(this) {
6599            ActivityStack stack = ActivityRecord.getStackLocked(token);
6600            if (stack != null) {
6601                stack.activityPausedLocked(token, false);
6602            }
6603        }
6604        Binder.restoreCallingIdentity(origId);
6605    }
6606
6607    @Override
6608    public final void activityStopped(IBinder token, Bundle icicle,
6609            PersistableBundle persistentState, CharSequence description) {
6610        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6611
6612        // Refuse possible leaked file descriptors
6613        if (icicle != null && icicle.hasFileDescriptors()) {
6614            throw new IllegalArgumentException("File descriptors passed in Bundle");
6615        }
6616
6617        final long origId = Binder.clearCallingIdentity();
6618
6619        synchronized (this) {
6620            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6621            if (r != null) {
6622                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6623            }
6624        }
6625
6626        trimApplications();
6627
6628        Binder.restoreCallingIdentity(origId);
6629    }
6630
6631    @Override
6632    public final void activityDestroyed(IBinder token) {
6633        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6634        synchronized (this) {
6635            ActivityStack stack = ActivityRecord.getStackLocked(token);
6636            if (stack != null) {
6637                stack.activityDestroyedLocked(token, "activityDestroyed");
6638            }
6639        }
6640    }
6641
6642    @Override
6643    public final void activityRelaunched(IBinder token) {
6644        final long origId = Binder.clearCallingIdentity();
6645        synchronized (this) {
6646            mStackSupervisor.activityRelaunchedLocked(token);
6647        }
6648        Binder.restoreCallingIdentity(origId);
6649    }
6650
6651    @Override
6652    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6653            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6654        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6655                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6656        synchronized (this) {
6657            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6658            if (record == null) {
6659                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6660                        + "found for: " + token);
6661            }
6662            record.setSizeConfigurations(horizontalSizeConfiguration,
6663                    verticalSizeConfigurations, smallestSizeConfigurations);
6664        }
6665    }
6666
6667    @Override
6668    public final void backgroundResourcesReleased(IBinder token) {
6669        final long origId = Binder.clearCallingIdentity();
6670        try {
6671            synchronized (this) {
6672                ActivityStack stack = ActivityRecord.getStackLocked(token);
6673                if (stack != null) {
6674                    stack.backgroundResourcesReleased();
6675                }
6676            }
6677        } finally {
6678            Binder.restoreCallingIdentity(origId);
6679        }
6680    }
6681
6682    @Override
6683    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6684        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6685    }
6686
6687    @Override
6688    public final void notifyEnterAnimationComplete(IBinder token) {
6689        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6690    }
6691
6692    @Override
6693    public String getCallingPackage(IBinder token) {
6694        synchronized (this) {
6695            ActivityRecord r = getCallingRecordLocked(token);
6696            return r != null ? r.info.packageName : null;
6697        }
6698    }
6699
6700    @Override
6701    public ComponentName getCallingActivity(IBinder token) {
6702        synchronized (this) {
6703            ActivityRecord r = getCallingRecordLocked(token);
6704            return r != null ? r.intent.getComponent() : null;
6705        }
6706    }
6707
6708    private ActivityRecord getCallingRecordLocked(IBinder token) {
6709        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6710        if (r == null) {
6711            return null;
6712        }
6713        return r.resultTo;
6714    }
6715
6716    @Override
6717    public ComponentName getActivityClassForToken(IBinder token) {
6718        synchronized(this) {
6719            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6720            if (r == null) {
6721                return null;
6722            }
6723            return r.intent.getComponent();
6724        }
6725    }
6726
6727    @Override
6728    public String getPackageForToken(IBinder token) {
6729        synchronized(this) {
6730            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6731            if (r == null) {
6732                return null;
6733            }
6734            return r.packageName;
6735        }
6736    }
6737
6738    @Override
6739    public boolean isRootVoiceInteraction(IBinder token) {
6740        synchronized(this) {
6741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6742            if (r == null) {
6743                return false;
6744            }
6745            return r.rootVoiceInteraction;
6746        }
6747    }
6748
6749    @Override
6750    public IIntentSender getIntentSender(int type,
6751            String packageName, IBinder token, String resultWho,
6752            int requestCode, Intent[] intents, String[] resolvedTypes,
6753            int flags, Bundle bOptions, int userId) {
6754        enforceNotIsolatedCaller("getIntentSender");
6755        // Refuse possible leaked file descriptors
6756        if (intents != null) {
6757            if (intents.length < 1) {
6758                throw new IllegalArgumentException("Intents array length must be >= 1");
6759            }
6760            for (int i=0; i<intents.length; i++) {
6761                Intent intent = intents[i];
6762                if (intent != null) {
6763                    if (intent.hasFileDescriptors()) {
6764                        throw new IllegalArgumentException("File descriptors passed in Intent");
6765                    }
6766                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6767                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6768                        throw new IllegalArgumentException(
6769                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6770                    }
6771                    intents[i] = new Intent(intent);
6772                }
6773            }
6774            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6775                throw new IllegalArgumentException(
6776                        "Intent array length does not match resolvedTypes length");
6777            }
6778        }
6779        if (bOptions != null) {
6780            if (bOptions.hasFileDescriptors()) {
6781                throw new IllegalArgumentException("File descriptors passed in options");
6782            }
6783        }
6784
6785        synchronized(this) {
6786            int callingUid = Binder.getCallingUid();
6787            int origUserId = userId;
6788            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6789                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6790                    ALLOW_NON_FULL, "getIntentSender", null);
6791            if (origUserId == UserHandle.USER_CURRENT) {
6792                // We don't want to evaluate this until the pending intent is
6793                // actually executed.  However, we do want to always do the
6794                // security checking for it above.
6795                userId = UserHandle.USER_CURRENT;
6796            }
6797            try {
6798                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6799                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6800                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6801                    if (!UserHandle.isSameApp(callingUid, uid)) {
6802                        String msg = "Permission Denial: getIntentSender() from pid="
6803                            + Binder.getCallingPid()
6804                            + ", uid=" + Binder.getCallingUid()
6805                            + ", (need uid=" + uid + ")"
6806                            + " is not allowed to send as package " + packageName;
6807                        Slog.w(TAG, msg);
6808                        throw new SecurityException(msg);
6809                    }
6810                }
6811
6812                return getIntentSenderLocked(type, packageName, callingUid, userId,
6813                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6814
6815            } catch (RemoteException e) {
6816                throw new SecurityException(e);
6817            }
6818        }
6819    }
6820
6821    IIntentSender getIntentSenderLocked(int type, String packageName,
6822            int callingUid, int userId, IBinder token, String resultWho,
6823            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6824            Bundle bOptions) {
6825        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6826        ActivityRecord activity = null;
6827        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6828            activity = ActivityRecord.isInStackLocked(token);
6829            if (activity == null) {
6830                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6831                return null;
6832            }
6833            if (activity.finishing) {
6834                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6835                return null;
6836            }
6837        }
6838
6839        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6840        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6841        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6842        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6843                |PendingIntent.FLAG_UPDATE_CURRENT);
6844
6845        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6846                type, packageName, activity, resultWho,
6847                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6848        WeakReference<PendingIntentRecord> ref;
6849        ref = mIntentSenderRecords.get(key);
6850        PendingIntentRecord rec = ref != null ? ref.get() : null;
6851        if (rec != null) {
6852            if (!cancelCurrent) {
6853                if (updateCurrent) {
6854                    if (rec.key.requestIntent != null) {
6855                        rec.key.requestIntent.replaceExtras(intents != null ?
6856                                intents[intents.length - 1] : null);
6857                    }
6858                    if (intents != null) {
6859                        intents[intents.length-1] = rec.key.requestIntent;
6860                        rec.key.allIntents = intents;
6861                        rec.key.allResolvedTypes = resolvedTypes;
6862                    } else {
6863                        rec.key.allIntents = null;
6864                        rec.key.allResolvedTypes = null;
6865                    }
6866                }
6867                return rec;
6868            }
6869            rec.canceled = true;
6870            mIntentSenderRecords.remove(key);
6871        }
6872        if (noCreate) {
6873            return rec;
6874        }
6875        rec = new PendingIntentRecord(this, key, callingUid);
6876        mIntentSenderRecords.put(key, rec.ref);
6877        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6878            if (activity.pendingResults == null) {
6879                activity.pendingResults
6880                        = new HashSet<WeakReference<PendingIntentRecord>>();
6881            }
6882            activity.pendingResults.add(rec.ref);
6883        }
6884        return rec;
6885    }
6886
6887    @Override
6888    public void cancelIntentSender(IIntentSender sender) {
6889        if (!(sender instanceof PendingIntentRecord)) {
6890            return;
6891        }
6892        synchronized(this) {
6893            PendingIntentRecord rec = (PendingIntentRecord)sender;
6894            try {
6895                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
6896                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
6897                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6898                    String msg = "Permission Denial: cancelIntentSender() from pid="
6899                        + Binder.getCallingPid()
6900                        + ", uid=" + Binder.getCallingUid()
6901                        + " is not allowed to cancel packges "
6902                        + rec.key.packageName;
6903                    Slog.w(TAG, msg);
6904                    throw new SecurityException(msg);
6905                }
6906            } catch (RemoteException e) {
6907                throw new SecurityException(e);
6908            }
6909            cancelIntentSenderLocked(rec, true);
6910        }
6911    }
6912
6913    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6914        rec.canceled = true;
6915        mIntentSenderRecords.remove(rec.key);
6916        if (cleanActivity && rec.key.activity != null) {
6917            rec.key.activity.pendingResults.remove(rec.ref);
6918        }
6919    }
6920
6921    @Override
6922    public String getPackageForIntentSender(IIntentSender pendingResult) {
6923        if (!(pendingResult instanceof PendingIntentRecord)) {
6924            return null;
6925        }
6926        try {
6927            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6928            return res.key.packageName;
6929        } catch (ClassCastException e) {
6930        }
6931        return null;
6932    }
6933
6934    @Override
6935    public int getUidForIntentSender(IIntentSender sender) {
6936        if (sender instanceof PendingIntentRecord) {
6937            try {
6938                PendingIntentRecord res = (PendingIntentRecord)sender;
6939                return res.uid;
6940            } catch (ClassCastException e) {
6941            }
6942        }
6943        return -1;
6944    }
6945
6946    @Override
6947    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6948        if (!(pendingResult instanceof PendingIntentRecord)) {
6949            return false;
6950        }
6951        try {
6952            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6953            if (res.key.allIntents == null) {
6954                return false;
6955            }
6956            for (int i=0; i<res.key.allIntents.length; i++) {
6957                Intent intent = res.key.allIntents[i];
6958                if (intent.getPackage() != null && intent.getComponent() != null) {
6959                    return false;
6960                }
6961            }
6962            return true;
6963        } catch (ClassCastException e) {
6964        }
6965        return false;
6966    }
6967
6968    @Override
6969    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6970        if (!(pendingResult instanceof PendingIntentRecord)) {
6971            return false;
6972        }
6973        try {
6974            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6975            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6976                return true;
6977            }
6978            return false;
6979        } catch (ClassCastException e) {
6980        }
6981        return false;
6982    }
6983
6984    @Override
6985    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6986        if (!(pendingResult instanceof PendingIntentRecord)) {
6987            return null;
6988        }
6989        try {
6990            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6991            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6992        } catch (ClassCastException e) {
6993        }
6994        return null;
6995    }
6996
6997    @Override
6998    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6999        if (!(pendingResult instanceof PendingIntentRecord)) {
7000            return null;
7001        }
7002        try {
7003            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7004            synchronized (this) {
7005                return getTagForIntentSenderLocked(res, prefix);
7006            }
7007        } catch (ClassCastException e) {
7008        }
7009        return null;
7010    }
7011
7012    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7013        final Intent intent = res.key.requestIntent;
7014        if (intent != null) {
7015            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7016                    || res.lastTagPrefix.equals(prefix))) {
7017                return res.lastTag;
7018            }
7019            res.lastTagPrefix = prefix;
7020            final StringBuilder sb = new StringBuilder(128);
7021            if (prefix != null) {
7022                sb.append(prefix);
7023            }
7024            if (intent.getAction() != null) {
7025                sb.append(intent.getAction());
7026            } else if (intent.getComponent() != null) {
7027                intent.getComponent().appendShortString(sb);
7028            } else {
7029                sb.append("?");
7030            }
7031            return res.lastTag = sb.toString();
7032        }
7033        return null;
7034    }
7035
7036    @Override
7037    public void setProcessLimit(int max) {
7038        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7039                "setProcessLimit()");
7040        synchronized (this) {
7041            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7042            mProcessLimitOverride = max;
7043        }
7044        trimApplications();
7045    }
7046
7047    @Override
7048    public int getProcessLimit() {
7049        synchronized (this) {
7050            return mProcessLimitOverride;
7051        }
7052    }
7053
7054    void foregroundTokenDied(ForegroundToken token) {
7055        synchronized (ActivityManagerService.this) {
7056            synchronized (mPidsSelfLocked) {
7057                ForegroundToken cur
7058                    = mForegroundProcesses.get(token.pid);
7059                if (cur != token) {
7060                    return;
7061                }
7062                mForegroundProcesses.remove(token.pid);
7063                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7064                if (pr == null) {
7065                    return;
7066                }
7067                pr.forcingToForeground = null;
7068                updateProcessForegroundLocked(pr, false, false);
7069            }
7070            updateOomAdjLocked();
7071        }
7072    }
7073
7074    @Override
7075    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7076        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7077                "setProcessForeground()");
7078        synchronized(this) {
7079            boolean changed = false;
7080
7081            synchronized (mPidsSelfLocked) {
7082                ProcessRecord pr = mPidsSelfLocked.get(pid);
7083                if (pr == null && isForeground) {
7084                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7085                    return;
7086                }
7087                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7088                if (oldToken != null) {
7089                    oldToken.token.unlinkToDeath(oldToken, 0);
7090                    mForegroundProcesses.remove(pid);
7091                    if (pr != null) {
7092                        pr.forcingToForeground = null;
7093                    }
7094                    changed = true;
7095                }
7096                if (isForeground && token != null) {
7097                    ForegroundToken newToken = new ForegroundToken() {
7098                        @Override
7099                        public void binderDied() {
7100                            foregroundTokenDied(this);
7101                        }
7102                    };
7103                    newToken.pid = pid;
7104                    newToken.token = token;
7105                    try {
7106                        token.linkToDeath(newToken, 0);
7107                        mForegroundProcesses.put(pid, newToken);
7108                        pr.forcingToForeground = token;
7109                        changed = true;
7110                    } catch (RemoteException e) {
7111                        // If the process died while doing this, we will later
7112                        // do the cleanup with the process death link.
7113                    }
7114                }
7115            }
7116
7117            if (changed) {
7118                updateOomAdjLocked();
7119            }
7120        }
7121    }
7122
7123    @Override
7124    public boolean isAppForeground(int uid) throws RemoteException {
7125        synchronized (this) {
7126            UidRecord uidRec = mActiveUids.get(uid);
7127            if (uidRec == null || uidRec.idle) {
7128                return false;
7129            }
7130            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7131        }
7132    }
7133
7134    @Override
7135    public boolean inMultiWindow(IBinder token) {
7136        final long origId = Binder.clearCallingIdentity();
7137        try {
7138            synchronized(this) {
7139                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7140                if (r == null) {
7141                    return false;
7142                }
7143                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7144                return !r.task.mFullscreen;
7145            }
7146        } finally {
7147            Binder.restoreCallingIdentity(origId);
7148        }
7149    }
7150
7151    @Override
7152    public boolean inPictureInPicture(IBinder token) {
7153        final long origId = Binder.clearCallingIdentity();
7154        try {
7155            synchronized(this) {
7156                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7157                if (stack == null) {
7158                    return false;
7159                }
7160                return stack.mStackId == PINNED_STACK_ID;
7161            }
7162        } finally {
7163            Binder.restoreCallingIdentity(origId);
7164        }
7165    }
7166
7167    @Override
7168    public void enterPictureInPicture(IBinder token) {
7169        final long origId = Binder.clearCallingIdentity();
7170        try {
7171            synchronized(this) {
7172                if (!mSupportsPictureInPicture) {
7173                    throw new IllegalStateException("enterPictureInPicture: "
7174                            + "Device doesn't support picture-in-picture mode.");
7175                }
7176
7177                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7178
7179                if (r == null) {
7180                    throw new IllegalStateException("enterPictureInPicture: "
7181                            + "Can't find activity for token=" + token);
7182                }
7183
7184                if (!r.supportsPictureInPicture()) {
7185                    throw new IllegalArgumentException("enterPictureInPicture: "
7186                            + "Picture-In-Picture not supported for r=" + r);
7187                }
7188
7189                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7190                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7191                        ? mDefaultPinnedStackBounds : null;
7192
7193                mStackSupervisor.moveActivityToPinnedStackLocked(
7194                        r, "enterPictureInPicture", bounds);
7195            }
7196        } finally {
7197            Binder.restoreCallingIdentity(origId);
7198        }
7199    }
7200
7201    // =========================================================
7202    // PROCESS INFO
7203    // =========================================================
7204
7205    static class ProcessInfoService extends IProcessInfoService.Stub {
7206        final ActivityManagerService mActivityManagerService;
7207        ProcessInfoService(ActivityManagerService activityManagerService) {
7208            mActivityManagerService = activityManagerService;
7209        }
7210
7211        @Override
7212        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7213            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7214                    /*in*/ pids, /*out*/ states, null);
7215        }
7216
7217        @Override
7218        public void getProcessStatesAndOomScoresFromPids(
7219                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7220            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7221                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7222        }
7223    }
7224
7225    /**
7226     * For each PID in the given input array, write the current process state
7227     * for that process into the states array, or -1 to indicate that no
7228     * process with the given PID exists. If scores array is provided, write
7229     * the oom score for the process into the scores array, with INVALID_ADJ
7230     * indicating the PID doesn't exist.
7231     */
7232    public void getProcessStatesAndOomScoresForPIDs(
7233            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7234        if (scores != null) {
7235            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7236                    "getProcessStatesAndOomScoresForPIDs()");
7237        }
7238
7239        if (pids == null) {
7240            throw new NullPointerException("pids");
7241        } else if (states == null) {
7242            throw new NullPointerException("states");
7243        } else if (pids.length != states.length) {
7244            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7245        } else if (scores != null && pids.length != scores.length) {
7246            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7247        }
7248
7249        synchronized (mPidsSelfLocked) {
7250            for (int i = 0; i < pids.length; i++) {
7251                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7252                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7253                        pr.curProcState;
7254                if (scores != null) {
7255                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7256                }
7257            }
7258        }
7259    }
7260
7261    // =========================================================
7262    // PERMISSIONS
7263    // =========================================================
7264
7265    static class PermissionController extends IPermissionController.Stub {
7266        ActivityManagerService mActivityManagerService;
7267        PermissionController(ActivityManagerService activityManagerService) {
7268            mActivityManagerService = activityManagerService;
7269        }
7270
7271        @Override
7272        public boolean checkPermission(String permission, int pid, int uid) {
7273            return mActivityManagerService.checkPermission(permission, pid,
7274                    uid) == PackageManager.PERMISSION_GRANTED;
7275        }
7276
7277        @Override
7278        public String[] getPackagesForUid(int uid) {
7279            return mActivityManagerService.mContext.getPackageManager()
7280                    .getPackagesForUid(uid);
7281        }
7282
7283        @Override
7284        public boolean isRuntimePermission(String permission) {
7285            try {
7286                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7287                        .getPermissionInfo(permission, 0);
7288                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7289            } catch (NameNotFoundException nnfe) {
7290                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7291            }
7292            return false;
7293        }
7294    }
7295
7296    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7297        @Override
7298        public int checkComponentPermission(String permission, int pid, int uid,
7299                int owningUid, boolean exported) {
7300            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7301                    owningUid, exported);
7302        }
7303
7304        @Override
7305        public Object getAMSLock() {
7306            return ActivityManagerService.this;
7307        }
7308    }
7309
7310    /**
7311     * This can be called with or without the global lock held.
7312     */
7313    int checkComponentPermission(String permission, int pid, int uid,
7314            int owningUid, boolean exported) {
7315        if (pid == MY_PID) {
7316            return PackageManager.PERMISSION_GRANTED;
7317        }
7318        return ActivityManager.checkComponentPermission(permission, uid,
7319                owningUid, exported);
7320    }
7321
7322    /**
7323     * As the only public entry point for permissions checking, this method
7324     * can enforce the semantic that requesting a check on a null global
7325     * permission is automatically denied.  (Internally a null permission
7326     * string is used when calling {@link #checkComponentPermission} in cases
7327     * when only uid-based security is needed.)
7328     *
7329     * This can be called with or without the global lock held.
7330     */
7331    @Override
7332    public int checkPermission(String permission, int pid, int uid) {
7333        if (permission == null) {
7334            return PackageManager.PERMISSION_DENIED;
7335        }
7336        return checkComponentPermission(permission, pid, uid, -1, true);
7337    }
7338
7339    @Override
7340    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7341        if (permission == null) {
7342            return PackageManager.PERMISSION_DENIED;
7343        }
7344
7345        // We might be performing an operation on behalf of an indirect binder
7346        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7347        // client identity accordingly before proceeding.
7348        Identity tlsIdentity = sCallerIdentity.get();
7349        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7350            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7351                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7352            uid = tlsIdentity.uid;
7353            pid = tlsIdentity.pid;
7354        }
7355
7356        return checkComponentPermission(permission, pid, uid, -1, true);
7357    }
7358
7359    /**
7360     * Binder IPC calls go through the public entry point.
7361     * This can be called with or without the global lock held.
7362     */
7363    int checkCallingPermission(String permission) {
7364        return checkPermission(permission,
7365                Binder.getCallingPid(),
7366                UserHandle.getAppId(Binder.getCallingUid()));
7367    }
7368
7369    /**
7370     * This can be called with or without the global lock held.
7371     */
7372    void enforceCallingPermission(String permission, String func) {
7373        if (checkCallingPermission(permission)
7374                == PackageManager.PERMISSION_GRANTED) {
7375            return;
7376        }
7377
7378        String msg = "Permission Denial: " + func + " from pid="
7379                + Binder.getCallingPid()
7380                + ", uid=" + Binder.getCallingUid()
7381                + " requires " + permission;
7382        Slog.w(TAG, msg);
7383        throw new SecurityException(msg);
7384    }
7385
7386    /**
7387     * Determine if UID is holding permissions required to access {@link Uri} in
7388     * the given {@link ProviderInfo}. Final permission checking is always done
7389     * in {@link ContentProvider}.
7390     */
7391    private final boolean checkHoldingPermissionsLocked(
7392            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7393        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7394                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7395        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7396            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7397                    != PERMISSION_GRANTED) {
7398                return false;
7399            }
7400        }
7401        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7402    }
7403
7404    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7405            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7406        if (pi.applicationInfo.uid == uid) {
7407            return true;
7408        } else if (!pi.exported) {
7409            return false;
7410        }
7411
7412        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7413        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7414        try {
7415            // check if target holds top-level <provider> permissions
7416            if (!readMet && pi.readPermission != null && considerUidPermissions
7417                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7418                readMet = true;
7419            }
7420            if (!writeMet && pi.writePermission != null && considerUidPermissions
7421                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7422                writeMet = true;
7423            }
7424
7425            // track if unprotected read/write is allowed; any denied
7426            // <path-permission> below removes this ability
7427            boolean allowDefaultRead = pi.readPermission == null;
7428            boolean allowDefaultWrite = pi.writePermission == null;
7429
7430            // check if target holds any <path-permission> that match uri
7431            final PathPermission[] pps = pi.pathPermissions;
7432            if (pps != null) {
7433                final String path = grantUri.uri.getPath();
7434                int i = pps.length;
7435                while (i > 0 && (!readMet || !writeMet)) {
7436                    i--;
7437                    PathPermission pp = pps[i];
7438                    if (pp.match(path)) {
7439                        if (!readMet) {
7440                            final String pprperm = pp.getReadPermission();
7441                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7442                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7443                                    + ": match=" + pp.match(path)
7444                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7445                            if (pprperm != null) {
7446                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7447                                        == PERMISSION_GRANTED) {
7448                                    readMet = true;
7449                                } else {
7450                                    allowDefaultRead = false;
7451                                }
7452                            }
7453                        }
7454                        if (!writeMet) {
7455                            final String ppwperm = pp.getWritePermission();
7456                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7457                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7458                                    + ": match=" + pp.match(path)
7459                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7460                            if (ppwperm != null) {
7461                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7462                                        == PERMISSION_GRANTED) {
7463                                    writeMet = true;
7464                                } else {
7465                                    allowDefaultWrite = false;
7466                                }
7467                            }
7468                        }
7469                    }
7470                }
7471            }
7472
7473            // grant unprotected <provider> read/write, if not blocked by
7474            // <path-permission> above
7475            if (allowDefaultRead) readMet = true;
7476            if (allowDefaultWrite) writeMet = true;
7477
7478        } catch (RemoteException e) {
7479            return false;
7480        }
7481
7482        return readMet && writeMet;
7483    }
7484
7485    public int getAppStartMode(int uid, String packageName) {
7486        synchronized (this) {
7487            return checkAllowBackgroundLocked(uid, packageName, -1);
7488        }
7489    }
7490
7491    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7492        UidRecord uidRec = mActiveUids.get(uid);
7493        if (!mLenientBackgroundCheck) {
7494            if (uidRec == null
7495                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7496                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7497                        packageName) != AppOpsManager.MODE_ALLOWED) {
7498                    return ActivityManager.APP_START_MODE_DELAYED;
7499                }
7500            }
7501
7502        } else if (uidRec == null || uidRec.idle) {
7503            if (callingPid >= 0) {
7504                ProcessRecord proc;
7505                synchronized (mPidsSelfLocked) {
7506                    proc = mPidsSelfLocked.get(callingPid);
7507                }
7508                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7509                    // Whoever is instigating this is in the foreground, so we will allow it
7510                    // to go through.
7511                    return ActivityManager.APP_START_MODE_NORMAL;
7512                }
7513            }
7514            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7515                    != AppOpsManager.MODE_ALLOWED) {
7516                return ActivityManager.APP_START_MODE_DELAYED;
7517            }
7518        }
7519        return ActivityManager.APP_START_MODE_NORMAL;
7520    }
7521
7522    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7523        ProviderInfo pi = null;
7524        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7525        if (cpr != null) {
7526            pi = cpr.info;
7527        } else {
7528            try {
7529                pi = AppGlobals.getPackageManager().resolveContentProvider(
7530                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7531            } catch (RemoteException ex) {
7532            }
7533        }
7534        return pi;
7535    }
7536
7537    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7538        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7539        if (targetUris != null) {
7540            return targetUris.get(grantUri);
7541        }
7542        return null;
7543    }
7544
7545    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7546            String targetPkg, int targetUid, GrantUri grantUri) {
7547        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7548        if (targetUris == null) {
7549            targetUris = Maps.newArrayMap();
7550            mGrantedUriPermissions.put(targetUid, targetUris);
7551        }
7552
7553        UriPermission perm = targetUris.get(grantUri);
7554        if (perm == null) {
7555            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7556            targetUris.put(grantUri, perm);
7557        }
7558
7559        return perm;
7560    }
7561
7562    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7563            final int modeFlags) {
7564        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7565        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7566                : UriPermission.STRENGTH_OWNED;
7567
7568        // Root gets to do everything.
7569        if (uid == 0) {
7570            return true;
7571        }
7572
7573        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7574        if (perms == null) return false;
7575
7576        // First look for exact match
7577        final UriPermission exactPerm = perms.get(grantUri);
7578        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7579            return true;
7580        }
7581
7582        // No exact match, look for prefixes
7583        final int N = perms.size();
7584        for (int i = 0; i < N; i++) {
7585            final UriPermission perm = perms.valueAt(i);
7586            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7587                    && perm.getStrength(modeFlags) >= minStrength) {
7588                return true;
7589            }
7590        }
7591
7592        return false;
7593    }
7594
7595    /**
7596     * @param uri This uri must NOT contain an embedded userId.
7597     * @param userId The userId in which the uri is to be resolved.
7598     */
7599    @Override
7600    public int checkUriPermission(Uri uri, int pid, int uid,
7601            final int modeFlags, int userId, IBinder callerToken) {
7602        enforceNotIsolatedCaller("checkUriPermission");
7603
7604        // Another redirected-binder-call permissions check as in
7605        // {@link checkPermissionWithToken}.
7606        Identity tlsIdentity = sCallerIdentity.get();
7607        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7608            uid = tlsIdentity.uid;
7609            pid = tlsIdentity.pid;
7610        }
7611
7612        // Our own process gets to do everything.
7613        if (pid == MY_PID) {
7614            return PackageManager.PERMISSION_GRANTED;
7615        }
7616        synchronized (this) {
7617            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7618                    ? PackageManager.PERMISSION_GRANTED
7619                    : PackageManager.PERMISSION_DENIED;
7620        }
7621    }
7622
7623    /**
7624     * Check if the targetPkg can be granted permission to access uri by
7625     * the callingUid using the given modeFlags.  Throws a security exception
7626     * if callingUid is not allowed to do this.  Returns the uid of the target
7627     * if the URI permission grant should be performed; returns -1 if it is not
7628     * needed (for example targetPkg already has permission to access the URI).
7629     * If you already know the uid of the target, you can supply it in
7630     * lastTargetUid else set that to -1.
7631     */
7632    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7633            final int modeFlags, int lastTargetUid) {
7634        if (!Intent.isAccessUriMode(modeFlags)) {
7635            return -1;
7636        }
7637
7638        if (targetPkg != null) {
7639            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7640                    "Checking grant " + targetPkg + " permission to " + grantUri);
7641        }
7642
7643        final IPackageManager pm = AppGlobals.getPackageManager();
7644
7645        // If this is not a content: uri, we can't do anything with it.
7646        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7647            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7648                    "Can't grant URI permission for non-content URI: " + grantUri);
7649            return -1;
7650        }
7651
7652        final String authority = grantUri.uri.getAuthority();
7653        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7654        if (pi == null) {
7655            Slog.w(TAG, "No content provider found for permission check: " +
7656                    grantUri.uri.toSafeString());
7657            return -1;
7658        }
7659
7660        int targetUid = lastTargetUid;
7661        if (targetUid < 0 && targetPkg != null) {
7662            try {
7663                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7664                        UserHandle.getUserId(callingUid));
7665                if (targetUid < 0) {
7666                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7667                            "Can't grant URI permission no uid for: " + targetPkg);
7668                    return -1;
7669                }
7670            } catch (RemoteException ex) {
7671                return -1;
7672            }
7673        }
7674
7675        if (targetUid >= 0) {
7676            // First...  does the target actually need this permission?
7677            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7678                // No need to grant the target this permission.
7679                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7680                        "Target " + targetPkg + " already has full permission to " + grantUri);
7681                return -1;
7682            }
7683        } else {
7684            // First...  there is no target package, so can anyone access it?
7685            boolean allowed = pi.exported;
7686            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7687                if (pi.readPermission != null) {
7688                    allowed = false;
7689                }
7690            }
7691            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7692                if (pi.writePermission != null) {
7693                    allowed = false;
7694                }
7695            }
7696            if (allowed) {
7697                return -1;
7698            }
7699        }
7700
7701        /* There is a special cross user grant if:
7702         * - The target is on another user.
7703         * - Apps on the current user can access the uri without any uid permissions.
7704         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7705         * grant uri permissions.
7706         */
7707        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7708                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7709                modeFlags, false /*without considering the uid permissions*/);
7710
7711        // Second...  is the provider allowing granting of URI permissions?
7712        if (!specialCrossUserGrant) {
7713            if (!pi.grantUriPermissions) {
7714                throw new SecurityException("Provider " + pi.packageName
7715                        + "/" + pi.name
7716                        + " does not allow granting of Uri permissions (uri "
7717                        + grantUri + ")");
7718            }
7719            if (pi.uriPermissionPatterns != null) {
7720                final int N = pi.uriPermissionPatterns.length;
7721                boolean allowed = false;
7722                for (int i=0; i<N; i++) {
7723                    if (pi.uriPermissionPatterns[i] != null
7724                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7725                        allowed = true;
7726                        break;
7727                    }
7728                }
7729                if (!allowed) {
7730                    throw new SecurityException("Provider " + pi.packageName
7731                            + "/" + pi.name
7732                            + " does not allow granting of permission to path of Uri "
7733                            + grantUri);
7734                }
7735            }
7736        }
7737
7738        // Third...  does the caller itself have permission to access
7739        // this uri?
7740        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7741            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7742                // Require they hold a strong enough Uri permission
7743                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7744                    throw new SecurityException("Uid " + callingUid
7745                            + " does not have permission to uri " + grantUri);
7746                }
7747            }
7748        }
7749        return targetUid;
7750    }
7751
7752    /**
7753     * @param uri This uri must NOT contain an embedded userId.
7754     * @param userId The userId in which the uri is to be resolved.
7755     */
7756    @Override
7757    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7758            final int modeFlags, int userId) {
7759        enforceNotIsolatedCaller("checkGrantUriPermission");
7760        synchronized(this) {
7761            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7762                    new GrantUri(userId, uri, false), modeFlags, -1);
7763        }
7764    }
7765
7766    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7767            final int modeFlags, UriPermissionOwner owner) {
7768        if (!Intent.isAccessUriMode(modeFlags)) {
7769            return;
7770        }
7771
7772        // So here we are: the caller has the assumed permission
7773        // to the uri, and the target doesn't.  Let's now give this to
7774        // the target.
7775
7776        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7777                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7778
7779        final String authority = grantUri.uri.getAuthority();
7780        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7781        if (pi == null) {
7782            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7783            return;
7784        }
7785
7786        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7787            grantUri.prefix = true;
7788        }
7789        final UriPermission perm = findOrCreateUriPermissionLocked(
7790                pi.packageName, targetPkg, targetUid, grantUri);
7791        perm.grantModes(modeFlags, owner);
7792    }
7793
7794    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7795            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7796        if (targetPkg == null) {
7797            throw new NullPointerException("targetPkg");
7798        }
7799        int targetUid;
7800        final IPackageManager pm = AppGlobals.getPackageManager();
7801        try {
7802            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7803        } catch (RemoteException ex) {
7804            return;
7805        }
7806
7807        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7808                targetUid);
7809        if (targetUid < 0) {
7810            return;
7811        }
7812
7813        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7814                owner);
7815    }
7816
7817    static class NeededUriGrants extends ArrayList<GrantUri> {
7818        final String targetPkg;
7819        final int targetUid;
7820        final int flags;
7821
7822        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7823            this.targetPkg = targetPkg;
7824            this.targetUid = targetUid;
7825            this.flags = flags;
7826        }
7827    }
7828
7829    /**
7830     * Like checkGrantUriPermissionLocked, but takes an Intent.
7831     */
7832    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7833            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7834        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7835                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7836                + " clip=" + (intent != null ? intent.getClipData() : null)
7837                + " from " + intent + "; flags=0x"
7838                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7839
7840        if (targetPkg == null) {
7841            throw new NullPointerException("targetPkg");
7842        }
7843
7844        if (intent == null) {
7845            return null;
7846        }
7847        Uri data = intent.getData();
7848        ClipData clip = intent.getClipData();
7849        if (data == null && clip == null) {
7850            return null;
7851        }
7852        // Default userId for uris in the intent (if they don't specify it themselves)
7853        int contentUserHint = intent.getContentUserHint();
7854        if (contentUserHint == UserHandle.USER_CURRENT) {
7855            contentUserHint = UserHandle.getUserId(callingUid);
7856        }
7857        final IPackageManager pm = AppGlobals.getPackageManager();
7858        int targetUid;
7859        if (needed != null) {
7860            targetUid = needed.targetUid;
7861        } else {
7862            try {
7863                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7864                        targetUserId);
7865            } catch (RemoteException ex) {
7866                return null;
7867            }
7868            if (targetUid < 0) {
7869                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7870                        "Can't grant URI permission no uid for: " + targetPkg
7871                        + " on user " + targetUserId);
7872                return null;
7873            }
7874        }
7875        if (data != null) {
7876            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7877            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7878                    targetUid);
7879            if (targetUid > 0) {
7880                if (needed == null) {
7881                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7882                }
7883                needed.add(grantUri);
7884            }
7885        }
7886        if (clip != null) {
7887            for (int i=0; i<clip.getItemCount(); i++) {
7888                Uri uri = clip.getItemAt(i).getUri();
7889                if (uri != null) {
7890                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7891                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7892                            targetUid);
7893                    if (targetUid > 0) {
7894                        if (needed == null) {
7895                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7896                        }
7897                        needed.add(grantUri);
7898                    }
7899                } else {
7900                    Intent clipIntent = clip.getItemAt(i).getIntent();
7901                    if (clipIntent != null) {
7902                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7903                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7904                        if (newNeeded != null) {
7905                            needed = newNeeded;
7906                        }
7907                    }
7908                }
7909            }
7910        }
7911
7912        return needed;
7913    }
7914
7915    /**
7916     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7917     */
7918    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7919            UriPermissionOwner owner) {
7920        if (needed != null) {
7921            for (int i=0; i<needed.size(); i++) {
7922                GrantUri grantUri = needed.get(i);
7923                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7924                        grantUri, needed.flags, owner);
7925            }
7926        }
7927    }
7928
7929    void grantUriPermissionFromIntentLocked(int callingUid,
7930            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7931        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7932                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7933        if (needed == null) {
7934            return;
7935        }
7936
7937        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7938    }
7939
7940    /**
7941     * @param uri This uri must NOT contain an embedded userId.
7942     * @param userId The userId in which the uri is to be resolved.
7943     */
7944    @Override
7945    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7946            final int modeFlags, int userId) {
7947        enforceNotIsolatedCaller("grantUriPermission");
7948        GrantUri grantUri = new GrantUri(userId, uri, false);
7949        synchronized(this) {
7950            final ProcessRecord r = getRecordForAppLocked(caller);
7951            if (r == null) {
7952                throw new SecurityException("Unable to find app for caller "
7953                        + caller
7954                        + " when granting permission to uri " + grantUri);
7955            }
7956            if (targetPkg == null) {
7957                throw new IllegalArgumentException("null target");
7958            }
7959            if (grantUri == null) {
7960                throw new IllegalArgumentException("null uri");
7961            }
7962
7963            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7964                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7965                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7966                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7967
7968            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7969                    UserHandle.getUserId(r.uid));
7970        }
7971    }
7972
7973    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7974        if (perm.modeFlags == 0) {
7975            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7976                    perm.targetUid);
7977            if (perms != null) {
7978                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7979                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7980
7981                perms.remove(perm.uri);
7982                if (perms.isEmpty()) {
7983                    mGrantedUriPermissions.remove(perm.targetUid);
7984                }
7985            }
7986        }
7987    }
7988
7989    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7990        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7991                "Revoking all granted permissions to " + grantUri);
7992
7993        final IPackageManager pm = AppGlobals.getPackageManager();
7994        final String authority = grantUri.uri.getAuthority();
7995        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7996        if (pi == null) {
7997            Slog.w(TAG, "No content provider found for permission revoke: "
7998                    + grantUri.toSafeString());
7999            return;
8000        }
8001
8002        // Does the caller have this permission on the URI?
8003        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8004            // If they don't have direct access to the URI, then revoke any
8005            // ownerless URI permissions that have been granted to them.
8006            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8007            if (perms != null) {
8008                boolean persistChanged = false;
8009                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8010                    final UriPermission perm = it.next();
8011                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8012                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8013                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                                "Revoking non-owned " + perm.targetUid
8015                                + " permission to " + perm.uri);
8016                        persistChanged |= perm.revokeModes(
8017                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8018                        if (perm.modeFlags == 0) {
8019                            it.remove();
8020                        }
8021                    }
8022                }
8023                if (perms.isEmpty()) {
8024                    mGrantedUriPermissions.remove(callingUid);
8025                }
8026                if (persistChanged) {
8027                    schedulePersistUriGrants();
8028                }
8029            }
8030            return;
8031        }
8032
8033        boolean persistChanged = false;
8034
8035        // Go through all of the permissions and remove any that match.
8036        int N = mGrantedUriPermissions.size();
8037        for (int i = 0; i < N; i++) {
8038            final int targetUid = mGrantedUriPermissions.keyAt(i);
8039            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8040
8041            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8042                final UriPermission perm = it.next();
8043                if (perm.uri.sourceUserId == grantUri.sourceUserId
8044                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8045                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8046                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8047                    persistChanged |= perm.revokeModes(
8048                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8049                    if (perm.modeFlags == 0) {
8050                        it.remove();
8051                    }
8052                }
8053            }
8054
8055            if (perms.isEmpty()) {
8056                mGrantedUriPermissions.remove(targetUid);
8057                N--;
8058                i--;
8059            }
8060        }
8061
8062        if (persistChanged) {
8063            schedulePersistUriGrants();
8064        }
8065    }
8066
8067    /**
8068     * @param uri This uri must NOT contain an embedded userId.
8069     * @param userId The userId in which the uri is to be resolved.
8070     */
8071    @Override
8072    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8073            int userId) {
8074        enforceNotIsolatedCaller("revokeUriPermission");
8075        synchronized(this) {
8076            final ProcessRecord r = getRecordForAppLocked(caller);
8077            if (r == null) {
8078                throw new SecurityException("Unable to find app for caller "
8079                        + caller
8080                        + " when revoking permission to uri " + uri);
8081            }
8082            if (uri == null) {
8083                Slog.w(TAG, "revokeUriPermission: null uri");
8084                return;
8085            }
8086
8087            if (!Intent.isAccessUriMode(modeFlags)) {
8088                return;
8089            }
8090
8091            final String authority = uri.getAuthority();
8092            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8093            if (pi == null) {
8094                Slog.w(TAG, "No content provider found for permission revoke: "
8095                        + uri.toSafeString());
8096                return;
8097            }
8098
8099            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8100        }
8101    }
8102
8103    /**
8104     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8105     * given package.
8106     *
8107     * @param packageName Package name to match, or {@code null} to apply to all
8108     *            packages.
8109     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8110     *            to all users.
8111     * @param persistable If persistable grants should be removed.
8112     */
8113    private void removeUriPermissionsForPackageLocked(
8114            String packageName, int userHandle, boolean persistable) {
8115        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8116            throw new IllegalArgumentException("Must narrow by either package or user");
8117        }
8118
8119        boolean persistChanged = false;
8120
8121        int N = mGrantedUriPermissions.size();
8122        for (int i = 0; i < N; i++) {
8123            final int targetUid = mGrantedUriPermissions.keyAt(i);
8124            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8125
8126            // Only inspect grants matching user
8127            if (userHandle == UserHandle.USER_ALL
8128                    || userHandle == UserHandle.getUserId(targetUid)) {
8129                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8130                    final UriPermission perm = it.next();
8131
8132                    // Only inspect grants matching package
8133                    if (packageName == null || perm.sourcePkg.equals(packageName)
8134                            || perm.targetPkg.equals(packageName)) {
8135                        persistChanged |= perm.revokeModes(persistable
8136                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8137
8138                        // Only remove when no modes remain; any persisted grants
8139                        // will keep this alive.
8140                        if (perm.modeFlags == 0) {
8141                            it.remove();
8142                        }
8143                    }
8144                }
8145
8146                if (perms.isEmpty()) {
8147                    mGrantedUriPermissions.remove(targetUid);
8148                    N--;
8149                    i--;
8150                }
8151            }
8152        }
8153
8154        if (persistChanged) {
8155            schedulePersistUriGrants();
8156        }
8157    }
8158
8159    @Override
8160    public IBinder newUriPermissionOwner(String name) {
8161        enforceNotIsolatedCaller("newUriPermissionOwner");
8162        synchronized(this) {
8163            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8164            return owner.getExternalTokenLocked();
8165        }
8166    }
8167
8168    @Override
8169    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8170        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8171        synchronized(this) {
8172            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8173            if (r == null) {
8174                throw new IllegalArgumentException("Activity does not exist; token="
8175                        + activityToken);
8176            }
8177            return r.getUriPermissionsLocked().getExternalTokenLocked();
8178        }
8179    }
8180    /**
8181     * @param uri This uri must NOT contain an embedded userId.
8182     * @param sourceUserId The userId in which the uri is to be resolved.
8183     * @param targetUserId The userId of the app that receives the grant.
8184     */
8185    @Override
8186    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8187            final int modeFlags, int sourceUserId, int targetUserId) {
8188        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8189                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8190                "grantUriPermissionFromOwner", null);
8191        synchronized(this) {
8192            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8193            if (owner == null) {
8194                throw new IllegalArgumentException("Unknown owner: " + token);
8195            }
8196            if (fromUid != Binder.getCallingUid()) {
8197                if (Binder.getCallingUid() != Process.myUid()) {
8198                    // Only system code can grant URI permissions on behalf
8199                    // of other users.
8200                    throw new SecurityException("nice try");
8201                }
8202            }
8203            if (targetPkg == null) {
8204                throw new IllegalArgumentException("null target");
8205            }
8206            if (uri == null) {
8207                throw new IllegalArgumentException("null uri");
8208            }
8209
8210            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8211                    modeFlags, owner, targetUserId);
8212        }
8213    }
8214
8215    /**
8216     * @param uri This uri must NOT contain an embedded userId.
8217     * @param userId The userId in which the uri is to be resolved.
8218     */
8219    @Override
8220    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8221        synchronized(this) {
8222            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8223            if (owner == null) {
8224                throw new IllegalArgumentException("Unknown owner: " + token);
8225            }
8226
8227            if (uri == null) {
8228                owner.removeUriPermissionsLocked(mode);
8229            } else {
8230                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8231            }
8232        }
8233    }
8234
8235    private void schedulePersistUriGrants() {
8236        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8237            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8238                    10 * DateUtils.SECOND_IN_MILLIS);
8239        }
8240    }
8241
8242    private void writeGrantedUriPermissions() {
8243        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8244
8245        // Snapshot permissions so we can persist without lock
8246        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8247        synchronized (this) {
8248            final int size = mGrantedUriPermissions.size();
8249            for (int i = 0; i < size; i++) {
8250                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8251                for (UriPermission perm : perms.values()) {
8252                    if (perm.persistedModeFlags != 0) {
8253                        persist.add(perm.snapshot());
8254                    }
8255                }
8256            }
8257        }
8258
8259        FileOutputStream fos = null;
8260        try {
8261            fos = mGrantFile.startWrite();
8262
8263            XmlSerializer out = new FastXmlSerializer();
8264            out.setOutput(fos, StandardCharsets.UTF_8.name());
8265            out.startDocument(null, true);
8266            out.startTag(null, TAG_URI_GRANTS);
8267            for (UriPermission.Snapshot perm : persist) {
8268                out.startTag(null, TAG_URI_GRANT);
8269                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8270                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8271                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8272                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8273                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8274                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8275                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8276                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8277                out.endTag(null, TAG_URI_GRANT);
8278            }
8279            out.endTag(null, TAG_URI_GRANTS);
8280            out.endDocument();
8281
8282            mGrantFile.finishWrite(fos);
8283        } catch (IOException e) {
8284            if (fos != null) {
8285                mGrantFile.failWrite(fos);
8286            }
8287        }
8288    }
8289
8290    private void readGrantedUriPermissionsLocked() {
8291        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8292
8293        final long now = System.currentTimeMillis();
8294
8295        FileInputStream fis = null;
8296        try {
8297            fis = mGrantFile.openRead();
8298            final XmlPullParser in = Xml.newPullParser();
8299            in.setInput(fis, StandardCharsets.UTF_8.name());
8300
8301            int type;
8302            while ((type = in.next()) != END_DOCUMENT) {
8303                final String tag = in.getName();
8304                if (type == START_TAG) {
8305                    if (TAG_URI_GRANT.equals(tag)) {
8306                        final int sourceUserId;
8307                        final int targetUserId;
8308                        final int userHandle = readIntAttribute(in,
8309                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8310                        if (userHandle != UserHandle.USER_NULL) {
8311                            // For backwards compatibility.
8312                            sourceUserId = userHandle;
8313                            targetUserId = userHandle;
8314                        } else {
8315                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8316                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8317                        }
8318                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8319                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8320                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8321                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8322                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8323                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8324
8325                        // Sanity check that provider still belongs to source package
8326                        final ProviderInfo pi = getProviderInfoLocked(
8327                                uri.getAuthority(), sourceUserId);
8328                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8329                            int targetUid = -1;
8330                            try {
8331                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8332                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8333                            } catch (RemoteException e) {
8334                            }
8335                            if (targetUid != -1) {
8336                                final UriPermission perm = findOrCreateUriPermissionLocked(
8337                                        sourcePkg, targetPkg, targetUid,
8338                                        new GrantUri(sourceUserId, uri, prefix));
8339                                perm.initPersistedModes(modeFlags, createdTime);
8340                            }
8341                        } else {
8342                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8343                                    + " but instead found " + pi);
8344                        }
8345                    }
8346                }
8347            }
8348        } catch (FileNotFoundException e) {
8349            // Missing grants is okay
8350        } catch (IOException e) {
8351            Slog.wtf(TAG, "Failed reading Uri grants", e);
8352        } catch (XmlPullParserException e) {
8353            Slog.wtf(TAG, "Failed reading Uri grants", e);
8354        } finally {
8355            IoUtils.closeQuietly(fis);
8356        }
8357    }
8358
8359    /**
8360     * @param uri This uri must NOT contain an embedded userId.
8361     * @param userId The userId in which the uri is to be resolved.
8362     */
8363    @Override
8364    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8365        enforceNotIsolatedCaller("takePersistableUriPermission");
8366
8367        Preconditions.checkFlagsArgument(modeFlags,
8368                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8369
8370        synchronized (this) {
8371            final int callingUid = Binder.getCallingUid();
8372            boolean persistChanged = false;
8373            GrantUri grantUri = new GrantUri(userId, uri, false);
8374
8375            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8376                    new GrantUri(userId, uri, false));
8377            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8378                    new GrantUri(userId, uri, true));
8379
8380            final boolean exactValid = (exactPerm != null)
8381                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8382            final boolean prefixValid = (prefixPerm != null)
8383                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8384
8385            if (!(exactValid || prefixValid)) {
8386                throw new SecurityException("No persistable permission grants found for UID "
8387                        + callingUid + " and Uri " + grantUri.toSafeString());
8388            }
8389
8390            if (exactValid) {
8391                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8392            }
8393            if (prefixValid) {
8394                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8395            }
8396
8397            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8398
8399            if (persistChanged) {
8400                schedulePersistUriGrants();
8401            }
8402        }
8403    }
8404
8405    /**
8406     * @param uri This uri must NOT contain an embedded userId.
8407     * @param userId The userId in which the uri is to be resolved.
8408     */
8409    @Override
8410    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8411        enforceNotIsolatedCaller("releasePersistableUriPermission");
8412
8413        Preconditions.checkFlagsArgument(modeFlags,
8414                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8415
8416        synchronized (this) {
8417            final int callingUid = Binder.getCallingUid();
8418            boolean persistChanged = false;
8419
8420            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8421                    new GrantUri(userId, uri, false));
8422            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8423                    new GrantUri(userId, uri, true));
8424            if (exactPerm == null && prefixPerm == null) {
8425                throw new SecurityException("No permission grants found for UID " + callingUid
8426                        + " and Uri " + uri.toSafeString());
8427            }
8428
8429            if (exactPerm != null) {
8430                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8431                removeUriPermissionIfNeededLocked(exactPerm);
8432            }
8433            if (prefixPerm != null) {
8434                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8435                removeUriPermissionIfNeededLocked(prefixPerm);
8436            }
8437
8438            if (persistChanged) {
8439                schedulePersistUriGrants();
8440            }
8441        }
8442    }
8443
8444    /**
8445     * Prune any older {@link UriPermission} for the given UID until outstanding
8446     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8447     *
8448     * @return if any mutations occured that require persisting.
8449     */
8450    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8451        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8452        if (perms == null) return false;
8453        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8454
8455        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8456        for (UriPermission perm : perms.values()) {
8457            if (perm.persistedModeFlags != 0) {
8458                persisted.add(perm);
8459            }
8460        }
8461
8462        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8463        if (trimCount <= 0) return false;
8464
8465        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8466        for (int i = 0; i < trimCount; i++) {
8467            final UriPermission perm = persisted.get(i);
8468
8469            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8470                    "Trimming grant created at " + perm.persistedCreateTime);
8471
8472            perm.releasePersistableModes(~0);
8473            removeUriPermissionIfNeededLocked(perm);
8474        }
8475
8476        return true;
8477    }
8478
8479    @Override
8480    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8481            String packageName, boolean incoming) {
8482        enforceNotIsolatedCaller("getPersistedUriPermissions");
8483        Preconditions.checkNotNull(packageName, "packageName");
8484
8485        final int callingUid = Binder.getCallingUid();
8486        final IPackageManager pm = AppGlobals.getPackageManager();
8487        try {
8488            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8489                    UserHandle.getUserId(callingUid));
8490            if (packageUid != callingUid) {
8491                throw new SecurityException(
8492                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8493            }
8494        } catch (RemoteException e) {
8495            throw new SecurityException("Failed to verify package name ownership");
8496        }
8497
8498        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8499        synchronized (this) {
8500            if (incoming) {
8501                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8502                        callingUid);
8503                if (perms == null) {
8504                    Slog.w(TAG, "No permission grants found for " + packageName);
8505                } else {
8506                    for (UriPermission perm : perms.values()) {
8507                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8508                            result.add(perm.buildPersistedPublicApiObject());
8509                        }
8510                    }
8511                }
8512            } else {
8513                final int size = mGrantedUriPermissions.size();
8514                for (int i = 0; i < size; i++) {
8515                    final ArrayMap<GrantUri, UriPermission> perms =
8516                            mGrantedUriPermissions.valueAt(i);
8517                    for (UriPermission perm : perms.values()) {
8518                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8519                            result.add(perm.buildPersistedPublicApiObject());
8520                        }
8521                    }
8522                }
8523            }
8524        }
8525        return new ParceledListSlice<android.content.UriPermission>(result);
8526    }
8527
8528    @Override
8529    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8530            String packageName, int userId) {
8531        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8532                "getGrantedUriPermissions");
8533
8534        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8535        synchronized (this) {
8536            final int size = mGrantedUriPermissions.size();
8537            for (int i = 0; i < size; i++) {
8538                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8539                for (UriPermission perm : perms.values()) {
8540                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8541                            && perm.persistedModeFlags != 0) {
8542                        result.add(perm.buildPersistedPublicApiObject());
8543                    }
8544                }
8545            }
8546        }
8547        return new ParceledListSlice<android.content.UriPermission>(result);
8548    }
8549
8550    @Override
8551    public void clearGrantedUriPermissions(String packageName, int userId) {
8552        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8553                "clearGrantedUriPermissions");
8554        removeUriPermissionsForPackageLocked(packageName, userId, true);
8555    }
8556
8557    @Override
8558    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8559        synchronized (this) {
8560            ProcessRecord app =
8561                who != null ? getRecordForAppLocked(who) : null;
8562            if (app == null) return;
8563
8564            Message msg = Message.obtain();
8565            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8566            msg.obj = app;
8567            msg.arg1 = waiting ? 1 : 0;
8568            mUiHandler.sendMessage(msg);
8569        }
8570    }
8571
8572    @Override
8573    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8574        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8575        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8576        outInfo.availMem = Process.getFreeMemory();
8577        outInfo.totalMem = Process.getTotalMemory();
8578        outInfo.threshold = homeAppMem;
8579        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8580        outInfo.hiddenAppThreshold = cachedAppMem;
8581        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8582                ProcessList.SERVICE_ADJ);
8583        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8584                ProcessList.VISIBLE_APP_ADJ);
8585        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8586                ProcessList.FOREGROUND_APP_ADJ);
8587    }
8588
8589    // =========================================================
8590    // TASK MANAGEMENT
8591    // =========================================================
8592
8593    @Override
8594    public List<IAppTask> getAppTasks(String callingPackage) {
8595        int callingUid = Binder.getCallingUid();
8596        long ident = Binder.clearCallingIdentity();
8597
8598        synchronized(this) {
8599            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8600            try {
8601                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8602
8603                final int N = mRecentTasks.size();
8604                for (int i = 0; i < N; i++) {
8605                    TaskRecord tr = mRecentTasks.get(i);
8606                    // Skip tasks that do not match the caller.  We don't need to verify
8607                    // callingPackage, because we are also limiting to callingUid and know
8608                    // that will limit to the correct security sandbox.
8609                    if (tr.effectiveUid != callingUid) {
8610                        continue;
8611                    }
8612                    Intent intent = tr.getBaseIntent();
8613                    if (intent == null ||
8614                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8615                        continue;
8616                    }
8617                    ActivityManager.RecentTaskInfo taskInfo =
8618                            createRecentTaskInfoFromTaskRecord(tr);
8619                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8620                    list.add(taskImpl);
8621                }
8622            } finally {
8623                Binder.restoreCallingIdentity(ident);
8624            }
8625            return list;
8626        }
8627    }
8628
8629    @Override
8630    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8631        final int callingUid = Binder.getCallingUid();
8632        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8633
8634        synchronized(this) {
8635            if (DEBUG_ALL) Slog.v(
8636                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8637
8638            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8639                    callingUid);
8640
8641            // TODO: Improve with MRU list from all ActivityStacks.
8642            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8643        }
8644
8645        return list;
8646    }
8647
8648    /**
8649     * Creates a new RecentTaskInfo from a TaskRecord.
8650     */
8651    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8652        // Update the task description to reflect any changes in the task stack
8653        tr.updateTaskDescription();
8654
8655        // Compose the recent task info
8656        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8657        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8658        rti.persistentId = tr.taskId;
8659        rti.baseIntent = new Intent(tr.getBaseIntent());
8660        rti.origActivity = tr.origActivity;
8661        rti.realActivity = tr.realActivity;
8662        rti.description = tr.lastDescription;
8663        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8664        rti.userId = tr.userId;
8665        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8666        rti.firstActiveTime = tr.firstActiveTime;
8667        rti.lastActiveTime = tr.lastActiveTime;
8668        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8669        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8670        rti.numActivities = 0;
8671        if (tr.mBounds != null) {
8672            rti.bounds = new Rect(tr.mBounds);
8673        }
8674        rti.isDockable = tr.canGoInDockedStack();
8675
8676        ActivityRecord base = null;
8677        ActivityRecord top = null;
8678        ActivityRecord tmp;
8679
8680        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8681            tmp = tr.mActivities.get(i);
8682            if (tmp.finishing) {
8683                continue;
8684            }
8685            base = tmp;
8686            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8687                top = base;
8688            }
8689            rti.numActivities++;
8690        }
8691
8692        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8693        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8694
8695        return rti;
8696    }
8697
8698    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8699        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8700                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8701        if (!allowed) {
8702            if (checkPermission(android.Manifest.permission.GET_TASKS,
8703                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8704                // Temporary compatibility: some existing apps on the system image may
8705                // still be requesting the old permission and not switched to the new
8706                // one; if so, we'll still allow them full access.  This means we need
8707                // to see if they are holding the old permission and are a system app.
8708                try {
8709                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8710                        allowed = true;
8711                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8712                                + " is using old GET_TASKS but privileged; allowing");
8713                    }
8714                } catch (RemoteException e) {
8715                }
8716            }
8717        }
8718        if (!allowed) {
8719            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8720                    + " does not hold REAL_GET_TASKS; limiting output");
8721        }
8722        return allowed;
8723    }
8724
8725    @Override
8726    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8727        final int callingUid = Binder.getCallingUid();
8728        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8729                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8730
8731        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8732        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8733        synchronized (this) {
8734            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8735                    callingUid);
8736            final boolean detailed = checkCallingPermission(
8737                    android.Manifest.permission.GET_DETAILED_TASKS)
8738                    == PackageManager.PERMISSION_GRANTED;
8739
8740            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8741                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8742                return Collections.emptyList();
8743            }
8744            mRecentTasks.loadUserRecentsLocked(userId);
8745
8746            final int recentsCount = mRecentTasks.size();
8747            ArrayList<ActivityManager.RecentTaskInfo> res =
8748                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8749
8750            final Set<Integer> includedUsers;
8751            if (includeProfiles) {
8752                includedUsers = mUserController.getProfileIds(userId);
8753            } else {
8754                includedUsers = new HashSet<>();
8755            }
8756            includedUsers.add(Integer.valueOf(userId));
8757
8758            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8759                TaskRecord tr = mRecentTasks.get(i);
8760                // Only add calling user or related users recent tasks
8761                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8762                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8763                    continue;
8764                }
8765
8766                if (tr.realActivitySuspended) {
8767                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8768                    continue;
8769                }
8770
8771                // Return the entry if desired by the caller.  We always return
8772                // the first entry, because callers always expect this to be the
8773                // foreground app.  We may filter others if the caller has
8774                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8775                // we should exclude the entry.
8776
8777                if (i == 0
8778                        || withExcluded
8779                        || (tr.intent == null)
8780                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8781                                == 0)) {
8782                    if (!allowed) {
8783                        // If the caller doesn't have the GET_TASKS permission, then only
8784                        // allow them to see a small subset of tasks -- their own and home.
8785                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8786                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8787                            continue;
8788                        }
8789                    }
8790                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8791                        if (tr.stack != null && tr.stack.isHomeStack()) {
8792                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8793                                    "Skipping, home stack task: " + tr);
8794                            continue;
8795                        }
8796                    }
8797                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8798                        if (tr.stack != null && tr.stack.isDockedStack()) {
8799                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8800                                    "Skipping, docked stack task: " + tr);
8801                            continue;
8802                        }
8803                    }
8804                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8805                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8806                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8807                                    "Skipping, pinned stack task: " + tr);
8808                            continue;
8809                        }
8810                    }
8811                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8812                        // Don't include auto remove tasks that are finished or finishing.
8813                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8814                                "Skipping, auto-remove without activity: " + tr);
8815                        continue;
8816                    }
8817                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8818                            && !tr.isAvailable) {
8819                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8820                                "Skipping, unavail real act: " + tr);
8821                        continue;
8822                    }
8823
8824                    if (!tr.mUserSetupComplete) {
8825                        // Don't include task launched while user is not done setting-up.
8826                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8827                                "Skipping, user setup not complete: " + tr);
8828                        continue;
8829                    }
8830
8831                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8832                    if (!detailed) {
8833                        rti.baseIntent.replaceExtras((Bundle)null);
8834                    }
8835
8836                    res.add(rti);
8837                    maxNum--;
8838                }
8839            }
8840            return res;
8841        }
8842    }
8843
8844    @Override
8845    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8846        synchronized (this) {
8847            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8848                    "getTaskThumbnail()");
8849            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8850                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8851            if (tr != null) {
8852                return tr.getTaskThumbnailLocked();
8853            }
8854        }
8855        return null;
8856    }
8857
8858    @Override
8859    public int addAppTask(IBinder activityToken, Intent intent,
8860            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8861        final int callingUid = Binder.getCallingUid();
8862        final long callingIdent = Binder.clearCallingIdentity();
8863
8864        try {
8865            synchronized (this) {
8866                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8867                if (r == null) {
8868                    throw new IllegalArgumentException("Activity does not exist; token="
8869                            + activityToken);
8870                }
8871                ComponentName comp = intent.getComponent();
8872                if (comp == null) {
8873                    throw new IllegalArgumentException("Intent " + intent
8874                            + " must specify explicit component");
8875                }
8876                if (thumbnail.getWidth() != mThumbnailWidth
8877                        || thumbnail.getHeight() != mThumbnailHeight) {
8878                    throw new IllegalArgumentException("Bad thumbnail size: got "
8879                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8880                            + mThumbnailWidth + "x" + mThumbnailHeight);
8881                }
8882                if (intent.getSelector() != null) {
8883                    intent.setSelector(null);
8884                }
8885                if (intent.getSourceBounds() != null) {
8886                    intent.setSourceBounds(null);
8887                }
8888                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8889                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8890                        // The caller has added this as an auto-remove task...  that makes no
8891                        // sense, so turn off auto-remove.
8892                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8893                    }
8894                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8895                    // Must be a new task.
8896                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8897                }
8898                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8899                    mLastAddedTaskActivity = null;
8900                }
8901                ActivityInfo ainfo = mLastAddedTaskActivity;
8902                if (ainfo == null) {
8903                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8904                            comp, 0, UserHandle.getUserId(callingUid));
8905                    if (ainfo.applicationInfo.uid != callingUid) {
8906                        throw new SecurityException(
8907                                "Can't add task for another application: target uid="
8908                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8909                    }
8910                }
8911
8912                // Use the full screen as the context for the task thumbnail
8913                final Point displaySize = new Point();
8914                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8915                r.task.stack.getDisplaySize(displaySize);
8916                thumbnailInfo.taskWidth = displaySize.x;
8917                thumbnailInfo.taskHeight = displaySize.y;
8918                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8919
8920                TaskRecord task = new TaskRecord(this,
8921                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
8922                        ainfo, intent, description, thumbnailInfo);
8923
8924                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8925                if (trimIdx >= 0) {
8926                    // If this would have caused a trim, then we'll abort because that
8927                    // means it would be added at the end of the list but then just removed.
8928                    return INVALID_TASK_ID;
8929                }
8930
8931                final int N = mRecentTasks.size();
8932                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8933                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8934                    tr.removedFromRecents();
8935                }
8936
8937                task.inRecents = true;
8938                mRecentTasks.add(task);
8939                r.task.stack.addTask(task, false, "addAppTask");
8940
8941                task.setLastThumbnailLocked(thumbnail);
8942                task.freeLastThumbnail();
8943
8944                return task.taskId;
8945            }
8946        } finally {
8947            Binder.restoreCallingIdentity(callingIdent);
8948        }
8949    }
8950
8951    @Override
8952    public Point getAppTaskThumbnailSize() {
8953        synchronized (this) {
8954            return new Point(mThumbnailWidth,  mThumbnailHeight);
8955        }
8956    }
8957
8958    @Override
8959    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8960        synchronized (this) {
8961            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8962            if (r != null) {
8963                r.setTaskDescription(td);
8964                r.task.updateTaskDescription();
8965            }
8966        }
8967    }
8968
8969    @Override
8970    public void setTaskResizeable(int taskId, int resizeableMode) {
8971        synchronized (this) {
8972            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8973                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8974            if (task == null) {
8975                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8976                return;
8977            }
8978            if (task.mResizeMode != resizeableMode) {
8979                task.mResizeMode = resizeableMode;
8980                mWindowManager.setTaskResizeable(taskId, resizeableMode);
8981                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8982                mStackSupervisor.resumeFocusedStackTopActivityLocked();
8983            }
8984        }
8985    }
8986
8987    @Override
8988    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8989        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
8990        long ident = Binder.clearCallingIdentity();
8991        try {
8992            synchronized (this) {
8993                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8994                if (task == null) {
8995                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8996                    return;
8997                }
8998                int stackId = task.stack.mStackId;
8999                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9000                // in crop windows resize mode or if the task size is affected by the docked stack
9001                // changing size. No need to update configuration.
9002                if (bounds != null && task.inCropWindowsResizeMode()
9003                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9004                    mWindowManager.scrollTask(task.taskId, bounds);
9005                    return;
9006                }
9007
9008                // Place the task in the right stack if it isn't there already based on
9009                // the requested bounds.
9010                // The stack transition logic is:
9011                // - a null bounds on a freeform task moves that task to fullscreen
9012                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9013                //   that task to freeform
9014                // - otherwise the task is not moved
9015                if (!StackId.isTaskResizeAllowed(stackId)) {
9016                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9017                }
9018                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9019                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9020                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9021                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9022                }
9023                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9024                if (stackId != task.stack.mStackId) {
9025                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9026                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9027                    preserveWindow = false;
9028                }
9029
9030                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
9031            }
9032        } finally {
9033            Binder.restoreCallingIdentity(ident);
9034        }
9035    }
9036
9037    @Override
9038    public Rect getTaskBounds(int taskId) {
9039        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9040        long ident = Binder.clearCallingIdentity();
9041        Rect rect = new Rect();
9042        try {
9043            synchronized (this) {
9044                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9045                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9046                if (task == null) {
9047                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9048                    return rect;
9049                }
9050                if (task.stack != null) {
9051                    // Return the bounds from window manager since it will be adjusted for various
9052                    // things like the presense of a docked stack for tasks that aren't resizeable.
9053                    mWindowManager.getTaskBounds(task.taskId, rect);
9054                } else {
9055                    // Task isn't in window manager yet since it isn't associated with a stack.
9056                    // Return the persist value from activity manager
9057                    if (task.mBounds != null) {
9058                        rect.set(task.mBounds);
9059                    } else if (task.mLastNonFullscreenBounds != null) {
9060                        rect.set(task.mLastNonFullscreenBounds);
9061                    }
9062                }
9063            }
9064        } finally {
9065            Binder.restoreCallingIdentity(ident);
9066        }
9067        return rect;
9068    }
9069
9070    @Override
9071    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9072        if (userId != UserHandle.getCallingUserId()) {
9073            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9074                    "getTaskDescriptionIcon");
9075        }
9076        final File passedIconFile = new File(filePath);
9077        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9078                passedIconFile.getName());
9079        if (!legitIconFile.getPath().equals(filePath)
9080                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9081            throw new IllegalArgumentException("Bad file path: " + filePath
9082                    + " passed for userId " + userId);
9083        }
9084        return mRecentTasks.getTaskDescriptionIcon(filePath);
9085    }
9086
9087    @Override
9088    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9089            throws RemoteException {
9090        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9091                opts.getCustomInPlaceResId() == 0) {
9092            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9093                    "with valid animation");
9094        }
9095        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9096        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9097                opts.getCustomInPlaceResId());
9098        mWindowManager.executeAppTransition();
9099    }
9100
9101    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9102            boolean removeFromRecents) {
9103        if (removeFromRecents) {
9104            mRecentTasks.remove(tr);
9105            tr.removedFromRecents();
9106        }
9107        ComponentName component = tr.getBaseIntent().getComponent();
9108        if (component == null) {
9109            Slog.w(TAG, "No component for base intent of task: " + tr);
9110            return;
9111        }
9112
9113        // Find any running services associated with this app and stop if needed.
9114        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9115
9116        if (!killProcess) {
9117            return;
9118        }
9119
9120        // Determine if the process(es) for this task should be killed.
9121        final String pkg = component.getPackageName();
9122        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9123        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9124        for (int i = 0; i < pmap.size(); i++) {
9125
9126            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9127            for (int j = 0; j < uids.size(); j++) {
9128                ProcessRecord proc = uids.valueAt(j);
9129                if (proc.userId != tr.userId) {
9130                    // Don't kill process for a different user.
9131                    continue;
9132                }
9133                if (proc == mHomeProcess) {
9134                    // Don't kill the home process along with tasks from the same package.
9135                    continue;
9136                }
9137                if (!proc.pkgList.containsKey(pkg)) {
9138                    // Don't kill process that is not associated with this task.
9139                    continue;
9140                }
9141
9142                for (int k = 0; k < proc.activities.size(); k++) {
9143                    TaskRecord otherTask = proc.activities.get(k).task;
9144                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9145                        // Don't kill process(es) that has an activity in a different task that is
9146                        // also in recents.
9147                        return;
9148                    }
9149                }
9150
9151                if (proc.foregroundServices) {
9152                    // Don't kill process(es) with foreground service.
9153                    return;
9154                }
9155
9156                // Add process to kill list.
9157                procsToKill.add(proc);
9158            }
9159        }
9160
9161        // Kill the running processes.
9162        for (int i = 0; i < procsToKill.size(); i++) {
9163            ProcessRecord pr = procsToKill.get(i);
9164            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9165                    && pr.curReceiver == null) {
9166                pr.kill("remove task", true);
9167            } else {
9168                // We delay killing processes that are not in the background or running a receiver.
9169                pr.waitingToKill = "remove task";
9170            }
9171        }
9172    }
9173
9174    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9175        // Remove all tasks with activities in the specified package from the list of recent tasks
9176        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9177            TaskRecord tr = mRecentTasks.get(i);
9178            if (tr.userId != userId) continue;
9179
9180            ComponentName cn = tr.intent.getComponent();
9181            if (cn != null && cn.getPackageName().equals(packageName)) {
9182                // If the package name matches, remove the task.
9183                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9184            }
9185        }
9186    }
9187
9188    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9189            int userId) {
9190
9191        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9192            TaskRecord tr = mRecentTasks.get(i);
9193            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9194                continue;
9195            }
9196
9197            ComponentName cn = tr.intent.getComponent();
9198            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9199                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9200            if (sameComponent) {
9201                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9202            }
9203        }
9204    }
9205
9206    /**
9207     * Removes the task with the specified task id.
9208     *
9209     * @param taskId Identifier of the task to be removed.
9210     * @param killProcess Kill any process associated with the task if possible.
9211     * @param removeFromRecents Whether to also remove the task from recents.
9212     * @return Returns true if the given task was found and removed.
9213     */
9214    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9215            boolean removeFromRecents) {
9216        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9217                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9218        if (tr != null) {
9219            tr.removeTaskActivitiesLocked();
9220            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9221            if (tr.isPersistable) {
9222                notifyTaskPersisterLocked(null, true);
9223            }
9224            return true;
9225        }
9226        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9227        return false;
9228    }
9229
9230    @Override
9231    public void removeStack(int stackId) {
9232        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9233        if (stackId == HOME_STACK_ID) {
9234            throw new IllegalArgumentException("Removing home stack is not allowed.");
9235        }
9236
9237        synchronized (this) {
9238            final long ident = Binder.clearCallingIdentity();
9239            try {
9240                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9241                if (stack == null) {
9242                    return;
9243                }
9244                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9245                for (int i = tasks.size() - 1; i >= 0; i--) {
9246                    removeTaskByIdLocked(
9247                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9248                }
9249            } finally {
9250                Binder.restoreCallingIdentity(ident);
9251            }
9252        }
9253    }
9254
9255    @Override
9256    public boolean removeTask(int taskId) {
9257        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9258        synchronized (this) {
9259            final long ident = Binder.clearCallingIdentity();
9260            try {
9261                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9262            } finally {
9263                Binder.restoreCallingIdentity(ident);
9264            }
9265        }
9266    }
9267
9268    /**
9269     * TODO: Add mController hook
9270     */
9271    @Override
9272    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9273        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9274
9275        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9276        synchronized(this) {
9277            moveTaskToFrontLocked(taskId, flags, bOptions);
9278        }
9279    }
9280
9281    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9282        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9283
9284        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9285                Binder.getCallingUid(), -1, -1, "Task to front")) {
9286            ActivityOptions.abort(options);
9287            return;
9288        }
9289        final long origId = Binder.clearCallingIdentity();
9290        try {
9291            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9292            if (task == null) {
9293                Slog.d(TAG, "Could not find task for id: "+ taskId);
9294                return;
9295            }
9296            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9297                mStackSupervisor.showLockTaskToast();
9298                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9299                return;
9300            }
9301            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9302            if (prev != null && prev.isRecentsActivity()) {
9303                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9304            }
9305            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9306        } finally {
9307            Binder.restoreCallingIdentity(origId);
9308        }
9309        ActivityOptions.abort(options);
9310    }
9311
9312    /**
9313     * Moves an activity, and all of the other activities within the same task, to the bottom
9314     * of the history stack.  The activity's order within the task is unchanged.
9315     *
9316     * @param token A reference to the activity we wish to move
9317     * @param nonRoot If false then this only works if the activity is the root
9318     *                of a task; if true it will work for any activity in a task.
9319     * @return Returns true if the move completed, false if not.
9320     */
9321    @Override
9322    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9323        enforceNotIsolatedCaller("moveActivityTaskToBack");
9324        synchronized(this) {
9325            final long origId = Binder.clearCallingIdentity();
9326            try {
9327                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9328                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9329                if (task != null) {
9330                    if (mStackSupervisor.isLockedTask(task)) {
9331                        mStackSupervisor.showLockTaskToast();
9332                        return false;
9333                    }
9334                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9335                }
9336            } finally {
9337                Binder.restoreCallingIdentity(origId);
9338            }
9339        }
9340        return false;
9341    }
9342
9343    @Override
9344    public void moveTaskBackwards(int task) {
9345        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9346                "moveTaskBackwards()");
9347
9348        synchronized(this) {
9349            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9350                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9351                return;
9352            }
9353            final long origId = Binder.clearCallingIdentity();
9354            moveTaskBackwardsLocked(task);
9355            Binder.restoreCallingIdentity(origId);
9356        }
9357    }
9358
9359    private final void moveTaskBackwardsLocked(int task) {
9360        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9361    }
9362
9363    @Override
9364    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9365            IActivityContainerCallback callback) throws RemoteException {
9366        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9367        synchronized (this) {
9368            if (parentActivityToken == null) {
9369                throw new IllegalArgumentException("parent token must not be null");
9370            }
9371            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9372            if (r == null) {
9373                return null;
9374            }
9375            if (callback == null) {
9376                throw new IllegalArgumentException("callback must not be null");
9377            }
9378            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9379        }
9380    }
9381
9382    @Override
9383    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9384        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9385        synchronized (this) {
9386            mStackSupervisor.deleteActivityContainer(container);
9387        }
9388    }
9389
9390    @Override
9391    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9392        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9393        synchronized (this) {
9394            final int stackId = mStackSupervisor.getNextStackId();
9395            final ActivityStack stack =
9396                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9397            if (stack == null) {
9398                return null;
9399            }
9400            return stack.mActivityContainer;
9401        }
9402    }
9403
9404    @Override
9405    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9406        synchronized (this) {
9407            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9408            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9409                return stack.mActivityContainer.getDisplayId();
9410            }
9411            return Display.DEFAULT_DISPLAY;
9412        }
9413    }
9414
9415    @Override
9416    public int getActivityStackId(IBinder token) throws RemoteException {
9417        synchronized (this) {
9418            ActivityStack stack = ActivityRecord.getStackLocked(token);
9419            if (stack == null) {
9420                return INVALID_STACK_ID;
9421            }
9422            return stack.mStackId;
9423        }
9424    }
9425
9426    @Override
9427    public void exitFreeformMode(IBinder token) throws RemoteException {
9428        synchronized (this) {
9429            long ident = Binder.clearCallingIdentity();
9430            try {
9431                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9432                if (r == null) {
9433                    throw new IllegalArgumentException(
9434                            "exitFreeformMode: No activity record matching token=" + token);
9435                }
9436                final ActivityStack stack = r.getStackLocked(token);
9437                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9438                    throw new IllegalStateException(
9439                            "exitFreeformMode: You can only go fullscreen from freeform.");
9440                }
9441                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9442                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9443                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9444            } finally {
9445                Binder.restoreCallingIdentity(ident);
9446            }
9447        }
9448    }
9449
9450    @Override
9451    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9452        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9453        if (stackId == HOME_STACK_ID) {
9454            throw new IllegalArgumentException(
9455                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9456        }
9457        synchronized (this) {
9458            long ident = Binder.clearCallingIdentity();
9459            try {
9460                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9461                        + " to stackId=" + stackId + " toTop=" + toTop);
9462                if (stackId == DOCKED_STACK_ID) {
9463                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9464                            null /* initialBounds */);
9465                }
9466                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9467                        "moveTaskToStack", ANIMATE);
9468            } finally {
9469                Binder.restoreCallingIdentity(ident);
9470            }
9471        }
9472    }
9473
9474    /**
9475     * Moves the input task to the docked stack.
9476     *
9477     * @param taskId Id of task to move.
9478     * @param createMode The mode the docked stack should be created in if it doesn't exist
9479     *                   already. See
9480     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9481     *                   and
9482     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9483     * @param toTop If the task and stack should be moved to the top.
9484     * @param animate Whether we should play an animation for the moving the task
9485     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9486     *                      docked stack. Pass {@code null} to use default bounds.
9487     */
9488    @Override
9489    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9490            Rect initialBounds) {
9491        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9492        synchronized (this) {
9493            long ident = Binder.clearCallingIdentity();
9494            try {
9495                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9496                        + " to createMode=" + createMode + " toTop=" + toTop);
9497                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9498                return mStackSupervisor.moveTaskToStackLocked(
9499                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9500                        "moveTaskToDockedStack", animate);
9501            } finally {
9502                Binder.restoreCallingIdentity(ident);
9503            }
9504        }
9505    }
9506
9507    /**
9508     * Moves the top activity in the input stackId to the pinned stack.
9509     *
9510     * @param stackId Id of stack to move the top activity to pinned stack.
9511     * @param bounds Bounds to use for pinned stack.
9512     *
9513     * @return True if the top activity of the input stack was successfully moved to the pinned
9514     *          stack.
9515     */
9516    @Override
9517    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9518        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9519        synchronized (this) {
9520            if (!mSupportsPictureInPicture) {
9521                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9522                        + "Device doesn't support picture-in-pciture mode");
9523            }
9524
9525            long ident = Binder.clearCallingIdentity();
9526            try {
9527                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9528            } finally {
9529                Binder.restoreCallingIdentity(ident);
9530            }
9531        }
9532    }
9533
9534    @Override
9535    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9536            boolean preserveWindows, boolean animate) {
9537        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9538        long ident = Binder.clearCallingIdentity();
9539        try {
9540            synchronized (this) {
9541                if (animate) {
9542                    if (stackId == PINNED_STACK_ID) {
9543                        mWindowManager.animateResizePinnedStack(bounds);
9544                    } else {
9545                        throw new IllegalArgumentException("Stack: " + stackId
9546                                + " doesn't support animated resize.");
9547                    }
9548                } else {
9549                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9550                            null /* tempTaskInsetBounds */, preserveWindows,
9551                            allowResizeInDockedMode);
9552                }
9553            }
9554        } finally {
9555            Binder.restoreCallingIdentity(ident);
9556        }
9557    }
9558
9559    @Override
9560    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9561            Rect tempDockedTaskInsetBounds,
9562            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9563        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9564                "resizeDockedStack()");
9565        long ident = Binder.clearCallingIdentity();
9566        try {
9567            synchronized (this) {
9568                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9569                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9570                        PRESERVE_WINDOWS);
9571            }
9572        } finally {
9573            Binder.restoreCallingIdentity(ident);
9574        }
9575    }
9576
9577    @Override
9578    public void positionTaskInStack(int taskId, int stackId, int position) {
9579        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9580        if (stackId == HOME_STACK_ID) {
9581            throw new IllegalArgumentException(
9582                    "positionTaskInStack: Attempt to change the position of task "
9583                    + taskId + " in/to home stack");
9584        }
9585        synchronized (this) {
9586            long ident = Binder.clearCallingIdentity();
9587            try {
9588                if (DEBUG_STACK) Slog.d(TAG_STACK,
9589                        "positionTaskInStack: positioning task=" + taskId
9590                        + " in stackId=" + stackId + " at position=" + position);
9591                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9592            } finally {
9593                Binder.restoreCallingIdentity(ident);
9594            }
9595        }
9596    }
9597
9598    @Override
9599    public List<StackInfo> getAllStackInfos() {
9600        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9601        long ident = Binder.clearCallingIdentity();
9602        try {
9603            synchronized (this) {
9604                return mStackSupervisor.getAllStackInfosLocked();
9605            }
9606        } finally {
9607            Binder.restoreCallingIdentity(ident);
9608        }
9609    }
9610
9611    @Override
9612    public StackInfo getStackInfo(int stackId) {
9613        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9614        long ident = Binder.clearCallingIdentity();
9615        try {
9616            synchronized (this) {
9617                return mStackSupervisor.getStackInfoLocked(stackId);
9618            }
9619        } finally {
9620            Binder.restoreCallingIdentity(ident);
9621        }
9622    }
9623
9624    @Override
9625    public boolean isInHomeStack(int taskId) {
9626        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9627        long ident = Binder.clearCallingIdentity();
9628        try {
9629            synchronized (this) {
9630                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9631                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9632                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9633            }
9634        } finally {
9635            Binder.restoreCallingIdentity(ident);
9636        }
9637    }
9638
9639    @Override
9640    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9641        synchronized(this) {
9642            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9643        }
9644    }
9645
9646    @Override
9647    public void updateDeviceOwner(String packageName) {
9648        final int callingUid = Binder.getCallingUid();
9649        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9650            throw new SecurityException("updateDeviceOwner called from non-system process");
9651        }
9652        synchronized (this) {
9653            mDeviceOwnerName = packageName;
9654        }
9655    }
9656
9657    @Override
9658    public void updateLockTaskPackages(int userId, String[] packages) {
9659        final int callingUid = Binder.getCallingUid();
9660        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9661            throw new SecurityException("updateLockTaskPackage called from non-system process");
9662        }
9663        synchronized (this) {
9664            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9665                    Arrays.toString(packages));
9666            mLockTaskPackages.put(userId, packages);
9667            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9668        }
9669    }
9670
9671
9672    void startLockTaskModeLocked(TaskRecord task) {
9673        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9674        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9675            return;
9676        }
9677
9678        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9679        // is initiated by system after the pinning request was shown and locked mode is initiated
9680        // by an authorized app directly
9681        final int callingUid = Binder.getCallingUid();
9682        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9683        long ident = Binder.clearCallingIdentity();
9684        try {
9685            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9686            if (!isSystemInitiated) {
9687                task.mLockTaskUid = callingUid;
9688                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9689                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9690                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9691                    StatusBarManagerInternal statusBarManager =
9692                            LocalServices.getService(StatusBarManagerInternal.class);
9693                    if (statusBarManager != null) {
9694                        statusBarManager.showScreenPinningRequest();
9695                    }
9696                    return;
9697                }
9698
9699                if (stack == null || task != stack.topTask()) {
9700                    throw new IllegalArgumentException("Invalid task, not in foreground");
9701                }
9702            }
9703            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9704                    "Locking fully");
9705            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9706                    ActivityManager.LOCK_TASK_MODE_PINNED :
9707                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9708                    "startLockTask", true);
9709        } finally {
9710            Binder.restoreCallingIdentity(ident);
9711        }
9712    }
9713
9714    @Override
9715    public void startLockTaskMode(int taskId) {
9716        synchronized (this) {
9717            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9718            if (task != null) {
9719                startLockTaskModeLocked(task);
9720            }
9721        }
9722    }
9723
9724    @Override
9725    public void startLockTaskMode(IBinder token) {
9726        synchronized (this) {
9727            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9728            if (r == null) {
9729                return;
9730            }
9731            final TaskRecord task = r.task;
9732            if (task != null) {
9733                startLockTaskModeLocked(task);
9734            }
9735        }
9736    }
9737
9738    @Override
9739    public void startLockTaskModeOnCurrent() throws RemoteException {
9740        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9741        long ident = Binder.clearCallingIdentity();
9742        try {
9743            synchronized (this) {
9744                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9745                if (r != null) {
9746                    startLockTaskModeLocked(r.task);
9747                }
9748            }
9749        } finally {
9750            Binder.restoreCallingIdentity(ident);
9751        }
9752    }
9753
9754    @Override
9755    public void stopLockTaskMode() {
9756        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9757        if (lockTask == null) {
9758            // Our work here is done.
9759            return;
9760        }
9761
9762        final int callingUid = Binder.getCallingUid();
9763        final int lockTaskUid = lockTask.mLockTaskUid;
9764        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9765        // It is possible lockTaskMode was started by the system process because
9766        // android:lockTaskMode is set to a locking value in the application manifest instead of
9767        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9768        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9769        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9770                callingUid != lockTaskUid
9771                && (lockTaskUid != 0
9772                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9773            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9774                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9775        }
9776
9777        long ident = Binder.clearCallingIdentity();
9778        try {
9779            Log.d(TAG, "stopLockTaskMode");
9780            // Stop lock task
9781            synchronized (this) {
9782                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9783                        "stopLockTask", true);
9784            }
9785        } finally {
9786            Binder.restoreCallingIdentity(ident);
9787        }
9788    }
9789
9790    @Override
9791    public void stopLockTaskModeOnCurrent() throws RemoteException {
9792        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9793        long ident = Binder.clearCallingIdentity();
9794        try {
9795            stopLockTaskMode();
9796        } finally {
9797            Binder.restoreCallingIdentity(ident);
9798        }
9799    }
9800
9801    @Override
9802    public boolean isInLockTaskMode() {
9803        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9804    }
9805
9806    @Override
9807    public int getLockTaskModeState() {
9808        synchronized (this) {
9809            return mStackSupervisor.getLockTaskModeState();
9810        }
9811    }
9812
9813    @Override
9814    public void showLockTaskEscapeMessage(IBinder token) {
9815        synchronized (this) {
9816            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9817            if (r == null) {
9818                return;
9819            }
9820            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9821        }
9822    }
9823
9824    // =========================================================
9825    // CONTENT PROVIDERS
9826    // =========================================================
9827
9828    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9829        List<ProviderInfo> providers = null;
9830        try {
9831            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9832                    .queryContentProviders(app.processName, app.uid,
9833                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9834                                    | MATCH_DEBUG_TRIAGED_MISSING);
9835            providers = slice != null ? slice.getList() : null;
9836        } catch (RemoteException ex) {
9837        }
9838        if (DEBUG_MU) Slog.v(TAG_MU,
9839                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9840        int userId = app.userId;
9841        if (providers != null) {
9842            int N = providers.size();
9843            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9844            for (int i=0; i<N; i++) {
9845                ProviderInfo cpi =
9846                    (ProviderInfo)providers.get(i);
9847                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9848                        cpi.name, cpi.flags);
9849                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9850                    // This is a singleton provider, but a user besides the
9851                    // default user is asking to initialize a process it runs
9852                    // in...  well, no, it doesn't actually run in this process,
9853                    // it runs in the process of the default user.  Get rid of it.
9854                    providers.remove(i);
9855                    N--;
9856                    i--;
9857                    continue;
9858                }
9859
9860                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9861                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9862                if (cpr == null) {
9863                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9864                    mProviderMap.putProviderByClass(comp, cpr);
9865                }
9866                if (DEBUG_MU) Slog.v(TAG_MU,
9867                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9868                app.pubProviders.put(cpi.name, cpr);
9869                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9870                    // Don't add this if it is a platform component that is marked
9871                    // to run in multiple processes, because this is actually
9872                    // part of the framework so doesn't make sense to track as a
9873                    // separate apk in the process.
9874                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9875                            mProcessStats);
9876                }
9877                notifyPackageUse(cpi.applicationInfo.packageName);
9878            }
9879        }
9880        return providers;
9881    }
9882
9883    /**
9884     * Check if {@link ProcessRecord} has a possible chance at accessing the
9885     * given {@link ProviderInfo}. Final permission checking is always done
9886     * in {@link ContentProvider}.
9887     */
9888    private final String checkContentProviderPermissionLocked(
9889            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9890        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9891        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9892        boolean checkedGrants = false;
9893        if (checkUser) {
9894            // Looking for cross-user grants before enforcing the typical cross-users permissions
9895            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9896            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9897                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9898                    return null;
9899                }
9900                checkedGrants = true;
9901            }
9902            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9903                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9904            if (userId != tmpTargetUserId) {
9905                // When we actually went to determine the final targer user ID, this ended
9906                // up different than our initial check for the authority.  This is because
9907                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9908                // SELF.  So we need to re-check the grants again.
9909                checkedGrants = false;
9910            }
9911        }
9912        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9913                cpi.applicationInfo.uid, cpi.exported)
9914                == PackageManager.PERMISSION_GRANTED) {
9915            return null;
9916        }
9917        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9918                cpi.applicationInfo.uid, cpi.exported)
9919                == PackageManager.PERMISSION_GRANTED) {
9920            return null;
9921        }
9922
9923        PathPermission[] pps = cpi.pathPermissions;
9924        if (pps != null) {
9925            int i = pps.length;
9926            while (i > 0) {
9927                i--;
9928                PathPermission pp = pps[i];
9929                String pprperm = pp.getReadPermission();
9930                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9931                        cpi.applicationInfo.uid, cpi.exported)
9932                        == PackageManager.PERMISSION_GRANTED) {
9933                    return null;
9934                }
9935                String ppwperm = pp.getWritePermission();
9936                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9937                        cpi.applicationInfo.uid, cpi.exported)
9938                        == PackageManager.PERMISSION_GRANTED) {
9939                    return null;
9940                }
9941            }
9942        }
9943        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9944            return null;
9945        }
9946
9947        String msg;
9948        if (!cpi.exported) {
9949            msg = "Permission Denial: opening provider " + cpi.name
9950                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9951                    + ", uid=" + callingUid + ") that is not exported from uid "
9952                    + cpi.applicationInfo.uid;
9953        } else {
9954            msg = "Permission Denial: opening provider " + cpi.name
9955                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9956                    + ", uid=" + callingUid + ") requires "
9957                    + cpi.readPermission + " or " + cpi.writePermission;
9958        }
9959        Slog.w(TAG, msg);
9960        return msg;
9961    }
9962
9963    /**
9964     * Returns if the ContentProvider has granted a uri to callingUid
9965     */
9966    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9967        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9968        if (perms != null) {
9969            for (int i=perms.size()-1; i>=0; i--) {
9970                GrantUri grantUri = perms.keyAt(i);
9971                if (grantUri.sourceUserId == userId || !checkUser) {
9972                    if (matchesProvider(grantUri.uri, cpi)) {
9973                        return true;
9974                    }
9975                }
9976            }
9977        }
9978        return false;
9979    }
9980
9981    /**
9982     * Returns true if the uri authority is one of the authorities specified in the provider.
9983     */
9984    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9985        String uriAuth = uri.getAuthority();
9986        String cpiAuth = cpi.authority;
9987        if (cpiAuth.indexOf(';') == -1) {
9988            return cpiAuth.equals(uriAuth);
9989        }
9990        String[] cpiAuths = cpiAuth.split(";");
9991        int length = cpiAuths.length;
9992        for (int i = 0; i < length; i++) {
9993            if (cpiAuths[i].equals(uriAuth)) return true;
9994        }
9995        return false;
9996    }
9997
9998    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9999            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10000        if (r != null) {
10001            for (int i=0; i<r.conProviders.size(); i++) {
10002                ContentProviderConnection conn = r.conProviders.get(i);
10003                if (conn.provider == cpr) {
10004                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10005                            "Adding provider requested by "
10006                            + r.processName + " from process "
10007                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10008                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10009                    if (stable) {
10010                        conn.stableCount++;
10011                        conn.numStableIncs++;
10012                    } else {
10013                        conn.unstableCount++;
10014                        conn.numUnstableIncs++;
10015                    }
10016                    return conn;
10017                }
10018            }
10019            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10020            if (stable) {
10021                conn.stableCount = 1;
10022                conn.numStableIncs = 1;
10023            } else {
10024                conn.unstableCount = 1;
10025                conn.numUnstableIncs = 1;
10026            }
10027            cpr.connections.add(conn);
10028            r.conProviders.add(conn);
10029            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10030            return conn;
10031        }
10032        cpr.addExternalProcessHandleLocked(externalProcessToken);
10033        return null;
10034    }
10035
10036    boolean decProviderCountLocked(ContentProviderConnection conn,
10037            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10038        if (conn != null) {
10039            cpr = conn.provider;
10040            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10041                    "Removing provider requested by "
10042                    + conn.client.processName + " from process "
10043                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10044                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10045            if (stable) {
10046                conn.stableCount--;
10047            } else {
10048                conn.unstableCount--;
10049            }
10050            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10051                cpr.connections.remove(conn);
10052                conn.client.conProviders.remove(conn);
10053                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10054                    // The client is more important than last activity -- note the time this
10055                    // is happening, so we keep the old provider process around a bit as last
10056                    // activity to avoid thrashing it.
10057                    if (cpr.proc != null) {
10058                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10059                    }
10060                }
10061                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10062                return true;
10063            }
10064            return false;
10065        }
10066        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10067        return false;
10068    }
10069
10070    private void checkTime(long startTime, String where) {
10071        long now = SystemClock.elapsedRealtime();
10072        if ((now-startTime) > 1000) {
10073            // If we are taking more than a second, log about it.
10074            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10075        }
10076    }
10077
10078    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10079            String name, IBinder token, boolean stable, int userId) {
10080        ContentProviderRecord cpr;
10081        ContentProviderConnection conn = null;
10082        ProviderInfo cpi = null;
10083
10084        synchronized(this) {
10085            long startTime = SystemClock.elapsedRealtime();
10086
10087            ProcessRecord r = null;
10088            if (caller != null) {
10089                r = getRecordForAppLocked(caller);
10090                if (r == null) {
10091                    throw new SecurityException(
10092                            "Unable to find app for caller " + caller
10093                          + " (pid=" + Binder.getCallingPid()
10094                          + ") when getting content provider " + name);
10095                }
10096            }
10097
10098            boolean checkCrossUser = true;
10099
10100            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10101
10102            // First check if this content provider has been published...
10103            cpr = mProviderMap.getProviderByName(name, userId);
10104            // If that didn't work, check if it exists for user 0 and then
10105            // verify that it's a singleton provider before using it.
10106            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10107                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10108                if (cpr != null) {
10109                    cpi = cpr.info;
10110                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10111                            cpi.name, cpi.flags)
10112                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10113                        userId = UserHandle.USER_SYSTEM;
10114                        checkCrossUser = false;
10115                    } else {
10116                        cpr = null;
10117                        cpi = null;
10118                    }
10119                }
10120            }
10121
10122            boolean providerRunning = cpr != null;
10123            if (providerRunning) {
10124                cpi = cpr.info;
10125                String msg;
10126                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10127                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10128                        != null) {
10129                    throw new SecurityException(msg);
10130                }
10131                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10132
10133                if (r != null && cpr.canRunHere(r)) {
10134                    // This provider has been published or is in the process
10135                    // of being published...  but it is also allowed to run
10136                    // in the caller's process, so don't make a connection
10137                    // and just let the caller instantiate its own instance.
10138                    ContentProviderHolder holder = cpr.newHolder(null);
10139                    // don't give caller the provider object, it needs
10140                    // to make its own.
10141                    holder.provider = null;
10142                    return holder;
10143                }
10144
10145                final long origId = Binder.clearCallingIdentity();
10146
10147                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10148
10149                // In this case the provider instance already exists, so we can
10150                // return it right away.
10151                conn = incProviderCountLocked(r, cpr, token, stable);
10152                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10153                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10154                        // If this is a perceptible app accessing the provider,
10155                        // make sure to count it as being accessed and thus
10156                        // back up on the LRU list.  This is good because
10157                        // content providers are often expensive to start.
10158                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10159                        updateLruProcessLocked(cpr.proc, false, null);
10160                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10161                    }
10162                }
10163
10164                if (cpr.proc != null) {
10165                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10166                    boolean success = updateOomAdjLocked(cpr.proc);
10167                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10168                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10169                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10170                    // NOTE: there is still a race here where a signal could be
10171                    // pending on the process even though we managed to update its
10172                    // adj level.  Not sure what to do about this, but at least
10173                    // the race is now smaller.
10174                    if (!success) {
10175                        // Uh oh...  it looks like the provider's process
10176                        // has been killed on us.  We need to wait for a new
10177                        // process to be started, and make sure its death
10178                        // doesn't kill our process.
10179                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10180                                + " is crashing; detaching " + r);
10181                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10182                        checkTime(startTime, "getContentProviderImpl: before appDied");
10183                        appDiedLocked(cpr.proc);
10184                        checkTime(startTime, "getContentProviderImpl: after appDied");
10185                        if (!lastRef) {
10186                            // This wasn't the last ref our process had on
10187                            // the provider...  we have now been killed, bail.
10188                            return null;
10189                        }
10190                        providerRunning = false;
10191                        conn = null;
10192                    }
10193                }
10194
10195                Binder.restoreCallingIdentity(origId);
10196            }
10197
10198            if (!providerRunning) {
10199                try {
10200                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10201                    cpi = AppGlobals.getPackageManager().
10202                        resolveContentProvider(name,
10203                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10204                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10205                } catch (RemoteException ex) {
10206                }
10207                if (cpi == null) {
10208                    return null;
10209                }
10210                // If the provider is a singleton AND
10211                // (it's a call within the same user || the provider is a
10212                // privileged app)
10213                // Then allow connecting to the singleton provider
10214                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10215                        cpi.name, cpi.flags)
10216                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10217                if (singleton) {
10218                    userId = UserHandle.USER_SYSTEM;
10219                }
10220                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10221                checkTime(startTime, "getContentProviderImpl: got app info for user");
10222
10223                String msg;
10224                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10225                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10226                        != null) {
10227                    throw new SecurityException(msg);
10228                }
10229                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10230
10231                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10232                        && !cpi.processName.equals("system")) {
10233                    // If this content provider does not run in the system
10234                    // process, and the system is not yet ready to run other
10235                    // processes, then fail fast instead of hanging.
10236                    throw new IllegalArgumentException(
10237                            "Attempt to launch content provider before system ready");
10238                }
10239
10240                // Make sure that the user who owns this provider is running.  If not,
10241                // we don't want to allow it to run.
10242                if (!mUserController.isUserRunningLocked(userId, 0)) {
10243                    Slog.w(TAG, "Unable to launch app "
10244                            + cpi.applicationInfo.packageName + "/"
10245                            + cpi.applicationInfo.uid + " for provider "
10246                            + name + ": user " + userId + " is stopped");
10247                    return null;
10248                }
10249
10250                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10251                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10252                cpr = mProviderMap.getProviderByClass(comp, userId);
10253                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10254                final boolean firstClass = cpr == null;
10255                if (firstClass) {
10256                    final long ident = Binder.clearCallingIdentity();
10257
10258                    // If permissions need a review before any of the app components can run,
10259                    // we return no provider and launch a review activity if the calling app
10260                    // is in the foreground.
10261                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10262                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10263                            return null;
10264                        }
10265                    }
10266
10267                    try {
10268                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10269                        ApplicationInfo ai =
10270                            AppGlobals.getPackageManager().
10271                                getApplicationInfo(
10272                                        cpi.applicationInfo.packageName,
10273                                        STOCK_PM_FLAGS, userId);
10274                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10275                        if (ai == null) {
10276                            Slog.w(TAG, "No package info for content provider "
10277                                    + cpi.name);
10278                            return null;
10279                        }
10280                        ai = getAppInfoForUser(ai, userId);
10281                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10282                    } catch (RemoteException ex) {
10283                        // pm is in same process, this will never happen.
10284                    } finally {
10285                        Binder.restoreCallingIdentity(ident);
10286                    }
10287                }
10288
10289                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10290
10291                if (r != null && cpr.canRunHere(r)) {
10292                    // If this is a multiprocess provider, then just return its
10293                    // info and allow the caller to instantiate it.  Only do
10294                    // this if the provider is the same user as the caller's
10295                    // process, or can run as root (so can be in any process).
10296                    return cpr.newHolder(null);
10297                }
10298
10299                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10300                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10301                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10302
10303                // This is single process, and our app is now connecting to it.
10304                // See if we are already in the process of launching this
10305                // provider.
10306                final int N = mLaunchingProviders.size();
10307                int i;
10308                for (i = 0; i < N; i++) {
10309                    if (mLaunchingProviders.get(i) == cpr) {
10310                        break;
10311                    }
10312                }
10313
10314                // If the provider is not already being launched, then get it
10315                // started.
10316                if (i >= N) {
10317                    final long origId = Binder.clearCallingIdentity();
10318
10319                    try {
10320                        // Content provider is now in use, its package can't be stopped.
10321                        try {
10322                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10323                            AppGlobals.getPackageManager().setPackageStoppedState(
10324                                    cpr.appInfo.packageName, false, userId);
10325                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10326                        } catch (RemoteException e) {
10327                        } catch (IllegalArgumentException e) {
10328                            Slog.w(TAG, "Failed trying to unstop package "
10329                                    + cpr.appInfo.packageName + ": " + e);
10330                        }
10331
10332                        // Use existing process if already started
10333                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10334                        ProcessRecord proc = getProcessRecordLocked(
10335                                cpi.processName, cpr.appInfo.uid, false);
10336                        if (proc != null && proc.thread != null) {
10337                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10338                                    "Installing in existing process " + proc);
10339                            if (!proc.pubProviders.containsKey(cpi.name)) {
10340                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10341                                proc.pubProviders.put(cpi.name, cpr);
10342                                try {
10343                                    proc.thread.scheduleInstallProvider(cpi);
10344                                } catch (RemoteException e) {
10345                                }
10346                            }
10347                        } else {
10348                            checkTime(startTime, "getContentProviderImpl: before start process");
10349                            proc = startProcessLocked(cpi.processName,
10350                                    cpr.appInfo, false, 0, "content provider",
10351                                    new ComponentName(cpi.applicationInfo.packageName,
10352                                            cpi.name), false, false, false);
10353                            checkTime(startTime, "getContentProviderImpl: after start process");
10354                            if (proc == null) {
10355                                Slog.w(TAG, "Unable to launch app "
10356                                        + cpi.applicationInfo.packageName + "/"
10357                                        + cpi.applicationInfo.uid + " for provider "
10358                                        + name + ": process is bad");
10359                                return null;
10360                            }
10361                        }
10362                        cpr.launchingApp = proc;
10363                        mLaunchingProviders.add(cpr);
10364                    } finally {
10365                        Binder.restoreCallingIdentity(origId);
10366                    }
10367                }
10368
10369                checkTime(startTime, "getContentProviderImpl: updating data structures");
10370
10371                // Make sure the provider is published (the same provider class
10372                // may be published under multiple names).
10373                if (firstClass) {
10374                    mProviderMap.putProviderByClass(comp, cpr);
10375                }
10376
10377                mProviderMap.putProviderByName(name, cpr);
10378                conn = incProviderCountLocked(r, cpr, token, stable);
10379                if (conn != null) {
10380                    conn.waiting = true;
10381                }
10382            }
10383            checkTime(startTime, "getContentProviderImpl: done!");
10384        }
10385
10386        // Wait for the provider to be published...
10387        synchronized (cpr) {
10388            while (cpr.provider == null) {
10389                if (cpr.launchingApp == null) {
10390                    Slog.w(TAG, "Unable to launch app "
10391                            + cpi.applicationInfo.packageName + "/"
10392                            + cpi.applicationInfo.uid + " for provider "
10393                            + name + ": launching app became null");
10394                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10395                            UserHandle.getUserId(cpi.applicationInfo.uid),
10396                            cpi.applicationInfo.packageName,
10397                            cpi.applicationInfo.uid, name);
10398                    return null;
10399                }
10400                try {
10401                    if (DEBUG_MU) Slog.v(TAG_MU,
10402                            "Waiting to start provider " + cpr
10403                            + " launchingApp=" + cpr.launchingApp);
10404                    if (conn != null) {
10405                        conn.waiting = true;
10406                    }
10407                    cpr.wait();
10408                } catch (InterruptedException ex) {
10409                } finally {
10410                    if (conn != null) {
10411                        conn.waiting = false;
10412                    }
10413                }
10414            }
10415        }
10416        return cpr != null ? cpr.newHolder(conn) : null;
10417    }
10418
10419    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10420            ProcessRecord r, final int userId) {
10421        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10422                cpi.packageName, r.userId)) {
10423
10424            final boolean callerForeground = r != null ? r.setSchedGroup
10425                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10426
10427            // Show a permission review UI only for starting from a foreground app
10428            if (!callerForeground) {
10429                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10430                        + cpi.packageName + " requires a permissions review");
10431                return false;
10432            }
10433
10434            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10435            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10436                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10437            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10438
10439            if (DEBUG_PERMISSIONS_REVIEW) {
10440                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10441                        + "for package " + cpi.packageName);
10442            }
10443
10444            final UserHandle userHandle = new UserHandle(userId);
10445            mHandler.post(new Runnable() {
10446                @Override
10447                public void run() {
10448                    mContext.startActivityAsUser(intent, userHandle);
10449                }
10450            });
10451
10452            return false;
10453        }
10454
10455        return true;
10456    }
10457
10458    PackageManagerInternal getPackageManagerInternalLocked() {
10459        if (mPackageManagerInt == null) {
10460            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10461        }
10462        return mPackageManagerInt;
10463    }
10464
10465    @Override
10466    public final ContentProviderHolder getContentProvider(
10467            IApplicationThread caller, String name, int userId, boolean stable) {
10468        enforceNotIsolatedCaller("getContentProvider");
10469        if (caller == null) {
10470            String msg = "null IApplicationThread when getting content provider "
10471                    + name;
10472            Slog.w(TAG, msg);
10473            throw new SecurityException(msg);
10474        }
10475        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10476        // with cross-user grant.
10477        return getContentProviderImpl(caller, name, null, stable, userId);
10478    }
10479
10480    public ContentProviderHolder getContentProviderExternal(
10481            String name, int userId, IBinder token) {
10482        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10483            "Do not have permission in call getContentProviderExternal()");
10484        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10485                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10486        return getContentProviderExternalUnchecked(name, token, userId);
10487    }
10488
10489    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10490            IBinder token, int userId) {
10491        return getContentProviderImpl(null, name, token, true, userId);
10492    }
10493
10494    /**
10495     * Drop a content provider from a ProcessRecord's bookkeeping
10496     */
10497    public void removeContentProvider(IBinder connection, boolean stable) {
10498        enforceNotIsolatedCaller("removeContentProvider");
10499        long ident = Binder.clearCallingIdentity();
10500        try {
10501            synchronized (this) {
10502                ContentProviderConnection conn;
10503                try {
10504                    conn = (ContentProviderConnection)connection;
10505                } catch (ClassCastException e) {
10506                    String msg ="removeContentProvider: " + connection
10507                            + " not a ContentProviderConnection";
10508                    Slog.w(TAG, msg);
10509                    throw new IllegalArgumentException(msg);
10510                }
10511                if (conn == null) {
10512                    throw new NullPointerException("connection is null");
10513                }
10514                if (decProviderCountLocked(conn, null, null, stable)) {
10515                    updateOomAdjLocked();
10516                }
10517            }
10518        } finally {
10519            Binder.restoreCallingIdentity(ident);
10520        }
10521    }
10522
10523    public void removeContentProviderExternal(String name, IBinder token) {
10524        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10525            "Do not have permission in call removeContentProviderExternal()");
10526        int userId = UserHandle.getCallingUserId();
10527        long ident = Binder.clearCallingIdentity();
10528        try {
10529            removeContentProviderExternalUnchecked(name, token, userId);
10530        } finally {
10531            Binder.restoreCallingIdentity(ident);
10532        }
10533    }
10534
10535    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10536        synchronized (this) {
10537            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10538            if(cpr == null) {
10539                //remove from mProvidersByClass
10540                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10541                return;
10542            }
10543
10544            //update content provider record entry info
10545            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10546            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10547            if (localCpr.hasExternalProcessHandles()) {
10548                if (localCpr.removeExternalProcessHandleLocked(token)) {
10549                    updateOomAdjLocked();
10550                } else {
10551                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10552                            + " with no external reference for token: "
10553                            + token + ".");
10554                }
10555            } else {
10556                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10557                        + " with no external references.");
10558            }
10559        }
10560    }
10561
10562    public final void publishContentProviders(IApplicationThread caller,
10563            List<ContentProviderHolder> providers) {
10564        if (providers == null) {
10565            return;
10566        }
10567
10568        enforceNotIsolatedCaller("publishContentProviders");
10569        synchronized (this) {
10570            final ProcessRecord r = getRecordForAppLocked(caller);
10571            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10572            if (r == null) {
10573                throw new SecurityException(
10574                        "Unable to find app for caller " + caller
10575                      + " (pid=" + Binder.getCallingPid()
10576                      + ") when publishing content providers");
10577            }
10578
10579            final long origId = Binder.clearCallingIdentity();
10580
10581            final int N = providers.size();
10582            for (int i = 0; i < N; i++) {
10583                ContentProviderHolder src = providers.get(i);
10584                if (src == null || src.info == null || src.provider == null) {
10585                    continue;
10586                }
10587                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10588                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10589                if (dst != null) {
10590                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10591                    mProviderMap.putProviderByClass(comp, dst);
10592                    String names[] = dst.info.authority.split(";");
10593                    for (int j = 0; j < names.length; j++) {
10594                        mProviderMap.putProviderByName(names[j], dst);
10595                    }
10596
10597                    int launchingCount = mLaunchingProviders.size();
10598                    int j;
10599                    boolean wasInLaunchingProviders = false;
10600                    for (j = 0; j < launchingCount; j++) {
10601                        if (mLaunchingProviders.get(j) == dst) {
10602                            mLaunchingProviders.remove(j);
10603                            wasInLaunchingProviders = true;
10604                            j--;
10605                            launchingCount--;
10606                        }
10607                    }
10608                    if (wasInLaunchingProviders) {
10609                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10610                    }
10611                    synchronized (dst) {
10612                        dst.provider = src.provider;
10613                        dst.proc = r;
10614                        dst.notifyAll();
10615                    }
10616                    updateOomAdjLocked(r);
10617                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10618                            src.info.authority);
10619                }
10620            }
10621
10622            Binder.restoreCallingIdentity(origId);
10623        }
10624    }
10625
10626    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10627        ContentProviderConnection conn;
10628        try {
10629            conn = (ContentProviderConnection)connection;
10630        } catch (ClassCastException e) {
10631            String msg ="refContentProvider: " + connection
10632                    + " not a ContentProviderConnection";
10633            Slog.w(TAG, msg);
10634            throw new IllegalArgumentException(msg);
10635        }
10636        if (conn == null) {
10637            throw new NullPointerException("connection is null");
10638        }
10639
10640        synchronized (this) {
10641            if (stable > 0) {
10642                conn.numStableIncs += stable;
10643            }
10644            stable = conn.stableCount + stable;
10645            if (stable < 0) {
10646                throw new IllegalStateException("stableCount < 0: " + stable);
10647            }
10648
10649            if (unstable > 0) {
10650                conn.numUnstableIncs += unstable;
10651            }
10652            unstable = conn.unstableCount + unstable;
10653            if (unstable < 0) {
10654                throw new IllegalStateException("unstableCount < 0: " + unstable);
10655            }
10656
10657            if ((stable+unstable) <= 0) {
10658                throw new IllegalStateException("ref counts can't go to zero here: stable="
10659                        + stable + " unstable=" + unstable);
10660            }
10661            conn.stableCount = stable;
10662            conn.unstableCount = unstable;
10663            return !conn.dead;
10664        }
10665    }
10666
10667    public void unstableProviderDied(IBinder connection) {
10668        ContentProviderConnection conn;
10669        try {
10670            conn = (ContentProviderConnection)connection;
10671        } catch (ClassCastException e) {
10672            String msg ="refContentProvider: " + connection
10673                    + " not a ContentProviderConnection";
10674            Slog.w(TAG, msg);
10675            throw new IllegalArgumentException(msg);
10676        }
10677        if (conn == null) {
10678            throw new NullPointerException("connection is null");
10679        }
10680
10681        // Safely retrieve the content provider associated with the connection.
10682        IContentProvider provider;
10683        synchronized (this) {
10684            provider = conn.provider.provider;
10685        }
10686
10687        if (provider == null) {
10688            // Um, yeah, we're way ahead of you.
10689            return;
10690        }
10691
10692        // Make sure the caller is being honest with us.
10693        if (provider.asBinder().pingBinder()) {
10694            // Er, no, still looks good to us.
10695            synchronized (this) {
10696                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10697                        + " says " + conn + " died, but we don't agree");
10698                return;
10699            }
10700        }
10701
10702        // Well look at that!  It's dead!
10703        synchronized (this) {
10704            if (conn.provider.provider != provider) {
10705                // But something changed...  good enough.
10706                return;
10707            }
10708
10709            ProcessRecord proc = conn.provider.proc;
10710            if (proc == null || proc.thread == null) {
10711                // Seems like the process is already cleaned up.
10712                return;
10713            }
10714
10715            // As far as we're concerned, this is just like receiving a
10716            // death notification...  just a bit prematurely.
10717            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10718                    + ") early provider death");
10719            final long ident = Binder.clearCallingIdentity();
10720            try {
10721                appDiedLocked(proc);
10722            } finally {
10723                Binder.restoreCallingIdentity(ident);
10724            }
10725        }
10726    }
10727
10728    @Override
10729    public void appNotRespondingViaProvider(IBinder connection) {
10730        enforceCallingPermission(
10731                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10732
10733        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10734        if (conn == null) {
10735            Slog.w(TAG, "ContentProviderConnection is null");
10736            return;
10737        }
10738
10739        final ProcessRecord host = conn.provider.proc;
10740        if (host == null) {
10741            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10742            return;
10743        }
10744
10745        final long token = Binder.clearCallingIdentity();
10746        try {
10747            mAppErrors.appNotResponding(host, null, null, false, "ContentProvider not responding");
10748        } finally {
10749            Binder.restoreCallingIdentity(token);
10750        }
10751    }
10752
10753    public final void installSystemProviders() {
10754        List<ProviderInfo> providers;
10755        synchronized (this) {
10756            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10757            providers = generateApplicationProvidersLocked(app);
10758            if (providers != null) {
10759                for (int i=providers.size()-1; i>=0; i--) {
10760                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10761                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10762                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10763                                + ": not system .apk");
10764                        providers.remove(i);
10765                    }
10766                }
10767            }
10768        }
10769        if (providers != null) {
10770            mSystemThread.installSystemProviders(providers);
10771        }
10772
10773        mCoreSettingsObserver = new CoreSettingsObserver(this);
10774        mFontScaleSettingObserver = new FontScaleSettingObserver();
10775
10776        //mUsageStatsService.monitorPackages();
10777    }
10778
10779    /**
10780     * When a user is unlocked, we need to install encryption-unaware providers
10781     * belonging to any running apps.
10782     */
10783    private void installEncryptionUnawareProviders(int userId) {
10784        if (!StorageManager.isFileBasedEncryptionEnabled()) {
10785            // TODO: eventually pivot this back to look at current user state,
10786            // similar to the comment in UserManager.isUserUnlocked(), but for
10787            // now, if we started apps when "unlocked" then unaware providers
10788            // have already been spun up.
10789            return;
10790        }
10791
10792        // We're only interested in providers that are encryption unaware, and
10793        // we don't care about uninstalled apps, since there's no way they're
10794        // running at this point.
10795        final int matchFlags = GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE
10796                | MATCH_DEBUG_TRIAGED_MISSING;
10797
10798        synchronized (this) {
10799            final int NP = mProcessNames.getMap().size();
10800            for (int ip = 0; ip < NP; ip++) {
10801                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10802                final int NA = apps.size();
10803                for (int ia = 0; ia < NA; ia++) {
10804                    final ProcessRecord app = apps.valueAt(ia);
10805                    if (app.userId != userId || app.thread == null) continue;
10806
10807                    final int NG = app.pkgList.size();
10808                    for (int ig = 0; ig < NG; ig++) {
10809                        try {
10810                            final String pkgName = app.pkgList.keyAt(ig);
10811                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10812                                    .getPackageInfo(pkgName, matchFlags, userId);
10813                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10814                                for (ProviderInfo provInfo : pkgInfo.providers) {
10815                                    Log.v(TAG, "Installing " + provInfo);
10816                                    app.thread.scheduleInstallProvider(provInfo);
10817                                }
10818                            }
10819                        } catch (RemoteException ignored) {
10820                        }
10821                    }
10822                }
10823            }
10824        }
10825    }
10826
10827    /**
10828     * Allows apps to retrieve the MIME type of a URI.
10829     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10830     * users, then it does not need permission to access the ContentProvider.
10831     * Either, it needs cross-user uri grants.
10832     *
10833     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10834     *
10835     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10836     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10837     */
10838    public String getProviderMimeType(Uri uri, int userId) {
10839        enforceNotIsolatedCaller("getProviderMimeType");
10840        final String name = uri.getAuthority();
10841        int callingUid = Binder.getCallingUid();
10842        int callingPid = Binder.getCallingPid();
10843        long ident = 0;
10844        boolean clearedIdentity = false;
10845        synchronized (this) {
10846            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10847        }
10848        if (canClearIdentity(callingPid, callingUid, userId)) {
10849            clearedIdentity = true;
10850            ident = Binder.clearCallingIdentity();
10851        }
10852        ContentProviderHolder holder = null;
10853        try {
10854            holder = getContentProviderExternalUnchecked(name, null, userId);
10855            if (holder != null) {
10856                return holder.provider.getType(uri);
10857            }
10858        } catch (RemoteException e) {
10859            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10860            return null;
10861        } finally {
10862            // We need to clear the identity to call removeContentProviderExternalUnchecked
10863            if (!clearedIdentity) {
10864                ident = Binder.clearCallingIdentity();
10865            }
10866            try {
10867                if (holder != null) {
10868                    removeContentProviderExternalUnchecked(name, null, userId);
10869                }
10870            } finally {
10871                Binder.restoreCallingIdentity(ident);
10872            }
10873        }
10874
10875        return null;
10876    }
10877
10878    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10879        if (UserHandle.getUserId(callingUid) == userId) {
10880            return true;
10881        }
10882        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10883                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10884                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10885                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10886                return true;
10887        }
10888        return false;
10889    }
10890
10891    // =========================================================
10892    // GLOBAL MANAGEMENT
10893    // =========================================================
10894
10895    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10896            boolean isolated, int isolatedUid) {
10897        String proc = customProcess != null ? customProcess : info.processName;
10898        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10899        final int userId = UserHandle.getUserId(info.uid);
10900        int uid = info.uid;
10901        if (isolated) {
10902            if (isolatedUid == 0) {
10903                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10904                while (true) {
10905                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10906                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10907                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10908                    }
10909                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10910                    mNextIsolatedProcessUid++;
10911                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10912                        // No process for this uid, use it.
10913                        break;
10914                    }
10915                    stepsLeft--;
10916                    if (stepsLeft <= 0) {
10917                        return null;
10918                    }
10919                }
10920            } else {
10921                // Special case for startIsolatedProcess (internal only), where
10922                // the uid of the isolated process is specified by the caller.
10923                uid = isolatedUid;
10924            }
10925        }
10926        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10927        if (!mBooted && !mBooting
10928                && userId == UserHandle.USER_SYSTEM
10929                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10930            r.persistent = true;
10931        }
10932        addProcessNameLocked(r);
10933        return r;
10934    }
10935
10936    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10937            String abiOverride) {
10938        ProcessRecord app;
10939        if (!isolated) {
10940            app = getProcessRecordLocked(info.processName, info.uid, true);
10941        } else {
10942            app = null;
10943        }
10944
10945        if (app == null) {
10946            app = newProcessRecordLocked(info, null, isolated, 0);
10947            updateLruProcessLocked(app, false, null);
10948            updateOomAdjLocked();
10949        }
10950
10951        // This package really, really can not be stopped.
10952        try {
10953            AppGlobals.getPackageManager().setPackageStoppedState(
10954                    info.packageName, false, UserHandle.getUserId(app.uid));
10955        } catch (RemoteException e) {
10956        } catch (IllegalArgumentException e) {
10957            Slog.w(TAG, "Failed trying to unstop package "
10958                    + info.packageName + ": " + e);
10959        }
10960
10961        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10962            app.persistent = true;
10963            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10964        }
10965        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10966            mPersistentStartingProcesses.add(app);
10967            startProcessLocked(app, "added application", app.processName, abiOverride,
10968                    null /* entryPoint */, null /* entryPointArgs */);
10969        }
10970
10971        return app;
10972    }
10973
10974    public void unhandledBack() {
10975        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10976                "unhandledBack()");
10977
10978        synchronized(this) {
10979            final long origId = Binder.clearCallingIdentity();
10980            try {
10981                getFocusedStack().unhandledBackLocked();
10982            } finally {
10983                Binder.restoreCallingIdentity(origId);
10984            }
10985        }
10986    }
10987
10988    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10989        enforceNotIsolatedCaller("openContentUri");
10990        final int userId = UserHandle.getCallingUserId();
10991        String name = uri.getAuthority();
10992        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10993        ParcelFileDescriptor pfd = null;
10994        if (cph != null) {
10995            // We record the binder invoker's uid in thread-local storage before
10996            // going to the content provider to open the file.  Later, in the code
10997            // that handles all permissions checks, we look for this uid and use
10998            // that rather than the Activity Manager's own uid.  The effect is that
10999            // we do the check against the caller's permissions even though it looks
11000            // to the content provider like the Activity Manager itself is making
11001            // the request.
11002            Binder token = new Binder();
11003            sCallerIdentity.set(new Identity(
11004                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11005            try {
11006                pfd = cph.provider.openFile(null, uri, "r", null, token);
11007            } catch (FileNotFoundException e) {
11008                // do nothing; pfd will be returned null
11009            } finally {
11010                // Ensure that whatever happens, we clean up the identity state
11011                sCallerIdentity.remove();
11012                // Ensure we're done with the provider.
11013                removeContentProviderExternalUnchecked(name, null, userId);
11014            }
11015        } else {
11016            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11017        }
11018        return pfd;
11019    }
11020
11021    // Actually is sleeping or shutting down or whatever else in the future
11022    // is an inactive state.
11023    public boolean isSleepingOrShuttingDown() {
11024        return isSleeping() || mShuttingDown;
11025    }
11026
11027    public boolean isSleeping() {
11028        return mSleeping;
11029    }
11030
11031    void onWakefulnessChanged(int wakefulness) {
11032        synchronized(this) {
11033            mWakefulness = wakefulness;
11034            updateSleepIfNeededLocked();
11035        }
11036    }
11037
11038    void finishRunningVoiceLocked() {
11039        Slog.d(TAG, "finishRunningVoiceLocked()  >>>>");
11040        if (mRunningVoice != null) {
11041            mRunningVoice = null;
11042            mVoiceWakeLock.release();
11043            updateSleepIfNeededLocked();
11044        }
11045    }
11046
11047    void startTimeTrackingFocusedActivityLocked() {
11048        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11049            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11050        }
11051    }
11052
11053    void updateSleepIfNeededLocked() {
11054        if (mSleeping && !shouldSleepLocked()) {
11055            mSleeping = false;
11056            startTimeTrackingFocusedActivityLocked();
11057            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11058            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11059            updateOomAdjLocked();
11060        } else if (!mSleeping && shouldSleepLocked()) {
11061            mSleeping = true;
11062            if (mCurAppTimeTracker != null) {
11063                mCurAppTimeTracker.stop();
11064            }
11065            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11066            mStackSupervisor.goingToSleepLocked();
11067            updateOomAdjLocked();
11068
11069            // Initialize the wake times of all processes.
11070            checkExcessivePowerUsageLocked(false);
11071            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11072            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11073            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11074        }
11075    }
11076
11077    private boolean shouldSleepLocked() {
11078        // Resume applications while running a voice interactor.
11079        if (mRunningVoice != null) {
11080            return false;
11081        }
11082
11083        // TODO: Transform the lock screen state into a sleep token instead.
11084        switch (mWakefulness) {
11085            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11086            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11087            case PowerManagerInternal.WAKEFULNESS_DOZING:
11088                // Pause applications whenever the lock screen is shown or any sleep
11089                // tokens have been acquired.
11090                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11091            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11092            default:
11093                // If we're asleep then pause applications unconditionally.
11094                return true;
11095        }
11096    }
11097
11098    /** Pokes the task persister. */
11099    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11100        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11101    }
11102
11103    /** Notifies all listeners when the task stack has changed. */
11104    void notifyTaskStackChangedLocked() {
11105        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11106        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11107        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11108        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11109    }
11110
11111    /** Notifies all listeners when an Activity is pinned. */
11112    void notifyActivityPinnedLocked() {
11113        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11114        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11115    }
11116
11117    /**
11118     * Notifies all listeners when an attempt was made to start an an activity that is already
11119     * running in the pinned stack and the activity was not actually started, but the task is
11120     * either brought to the front or a new Intent is delivered to it.
11121     */
11122    void notifyPinnedActivityRestartAttemptLocked() {
11123        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11124        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11125    }
11126
11127    /** Notifies all listeners when the pinned stack animation ends. */
11128    @Override
11129    public void notifyPinnedStackAnimationEnded() {
11130        synchronized (this) {
11131            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11132            mHandler.obtainMessage(
11133                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11134        }
11135    }
11136
11137    @Override
11138    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11139        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11140    }
11141
11142    @Override
11143    public boolean shutdown(int timeout) {
11144        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11145                != PackageManager.PERMISSION_GRANTED) {
11146            throw new SecurityException("Requires permission "
11147                    + android.Manifest.permission.SHUTDOWN);
11148        }
11149
11150        boolean timedout = false;
11151
11152        synchronized(this) {
11153            mShuttingDown = true;
11154            updateEventDispatchingLocked();
11155            timedout = mStackSupervisor.shutdownLocked(timeout);
11156        }
11157
11158        mAppOpsService.shutdown();
11159        if (mUsageStatsService != null) {
11160            mUsageStatsService.prepareShutdown();
11161        }
11162        mBatteryStatsService.shutdown();
11163        synchronized (this) {
11164            mProcessStats.shutdownLocked();
11165            notifyTaskPersisterLocked(null, true);
11166        }
11167
11168        return timedout;
11169    }
11170
11171    public final void activitySlept(IBinder token) {
11172        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11173
11174        final long origId = Binder.clearCallingIdentity();
11175
11176        synchronized (this) {
11177            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11178            if (r != null) {
11179                mStackSupervisor.activitySleptLocked(r);
11180            }
11181        }
11182
11183        Binder.restoreCallingIdentity(origId);
11184    }
11185
11186    private String lockScreenShownToString() {
11187        switch (mLockScreenShown) {
11188            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11189            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11190            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11191            default: return "Unknown=" + mLockScreenShown;
11192        }
11193    }
11194
11195    void logLockScreen(String msg) {
11196        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11197                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11198                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11199                + " mSleeping=" + mSleeping);
11200    }
11201
11202    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11203        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11204        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11205        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11206            boolean wasRunningVoice = mRunningVoice != null;
11207            mRunningVoice = session;
11208            if (!wasRunningVoice) {
11209                mVoiceWakeLock.acquire();
11210                updateSleepIfNeededLocked();
11211            }
11212        }
11213    }
11214
11215    private void updateEventDispatchingLocked() {
11216        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11217    }
11218
11219    public void setLockScreenShown(boolean shown) {
11220        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11221                != PackageManager.PERMISSION_GRANTED) {
11222            throw new SecurityException("Requires permission "
11223                    + android.Manifest.permission.DEVICE_POWER);
11224        }
11225
11226        final int user = UserHandle.myUserId();
11227        synchronized(this) {
11228            long ident = Binder.clearCallingIdentity();
11229            try {
11230                if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
11231                    startHomeActivityLocked(user, "setLockScreenShown");
11232                }
11233                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11234                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11235                updateSleepIfNeededLocked();
11236            } finally {
11237                Binder.restoreCallingIdentity(ident);
11238            }
11239        }
11240    }
11241
11242    @Override
11243    public void stopAppSwitches() {
11244        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11245                != PackageManager.PERMISSION_GRANTED) {
11246            throw new SecurityException("viewquires permission "
11247                    + android.Manifest.permission.STOP_APP_SWITCHES);
11248        }
11249
11250        synchronized(this) {
11251            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11252                    + APP_SWITCH_DELAY_TIME;
11253            mDidAppSwitch = false;
11254            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11255            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11256            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11257        }
11258    }
11259
11260    public void resumeAppSwitches() {
11261        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11262                != PackageManager.PERMISSION_GRANTED) {
11263            throw new SecurityException("Requires permission "
11264                    + android.Manifest.permission.STOP_APP_SWITCHES);
11265        }
11266
11267        synchronized(this) {
11268            // Note that we don't execute any pending app switches... we will
11269            // let those wait until either the timeout, or the next start
11270            // activity request.
11271            mAppSwitchesAllowedTime = 0;
11272        }
11273    }
11274
11275    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11276            int callingPid, int callingUid, String name) {
11277        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11278            return true;
11279        }
11280
11281        int perm = checkComponentPermission(
11282                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11283                sourceUid, -1, true);
11284        if (perm == PackageManager.PERMISSION_GRANTED) {
11285            return true;
11286        }
11287
11288        // If the actual IPC caller is different from the logical source, then
11289        // also see if they are allowed to control app switches.
11290        if (callingUid != -1 && callingUid != sourceUid) {
11291            perm = checkComponentPermission(
11292                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11293                    callingUid, -1, true);
11294            if (perm == PackageManager.PERMISSION_GRANTED) {
11295                return true;
11296            }
11297        }
11298
11299        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11300        return false;
11301    }
11302
11303    public void setDebugApp(String packageName, boolean waitForDebugger,
11304            boolean persistent) {
11305        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11306                "setDebugApp()");
11307
11308        long ident = Binder.clearCallingIdentity();
11309        try {
11310            // Note that this is not really thread safe if there are multiple
11311            // callers into it at the same time, but that's not a situation we
11312            // care about.
11313            if (persistent) {
11314                final ContentResolver resolver = mContext.getContentResolver();
11315                Settings.Global.putString(
11316                    resolver, Settings.Global.DEBUG_APP,
11317                    packageName);
11318                Settings.Global.putInt(
11319                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11320                    waitForDebugger ? 1 : 0);
11321            }
11322
11323            synchronized (this) {
11324                if (!persistent) {
11325                    mOrigDebugApp = mDebugApp;
11326                    mOrigWaitForDebugger = mWaitForDebugger;
11327                }
11328                mDebugApp = packageName;
11329                mWaitForDebugger = waitForDebugger;
11330                mDebugTransient = !persistent;
11331                if (packageName != null) {
11332                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11333                            false, UserHandle.USER_ALL, "set debug app");
11334                }
11335            }
11336        } finally {
11337            Binder.restoreCallingIdentity(ident);
11338        }
11339    }
11340
11341    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11342        synchronized (this) {
11343            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11344            if (!isDebuggable) {
11345                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11346                    throw new SecurityException("Process not debuggable: " + app.packageName);
11347                }
11348            }
11349
11350            mTrackAllocationApp = processName;
11351        }
11352    }
11353
11354    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11355        synchronized (this) {
11356            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11357            if (!isDebuggable) {
11358                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11359                    throw new SecurityException("Process not debuggable: " + app.packageName);
11360                }
11361            }
11362            mProfileApp = processName;
11363            mProfileFile = profilerInfo.profileFile;
11364            if (mProfileFd != null) {
11365                try {
11366                    mProfileFd.close();
11367                } catch (IOException e) {
11368                }
11369                mProfileFd = null;
11370            }
11371            mProfileFd = profilerInfo.profileFd;
11372            mSamplingInterval = profilerInfo.samplingInterval;
11373            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11374            mProfileType = 0;
11375        }
11376    }
11377
11378    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11379        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11380        if (!isDebuggable) {
11381            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11382                throw new SecurityException("Process not debuggable: " + app.packageName);
11383            }
11384        }
11385        mNativeDebuggingApp = processName;
11386    }
11387
11388    @Override
11389    public void setAlwaysFinish(boolean enabled) {
11390        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11391                "setAlwaysFinish()");
11392
11393        long ident = Binder.clearCallingIdentity();
11394        try {
11395            Settings.Global.putInt(
11396                    mContext.getContentResolver(),
11397                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11398
11399            synchronized (this) {
11400                mAlwaysFinishActivities = enabled;
11401            }
11402        } finally {
11403            Binder.restoreCallingIdentity(ident);
11404        }
11405    }
11406
11407    @Override
11408    public void setLenientBackgroundCheck(boolean enabled) {
11409        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11410                "setLenientBackgroundCheck()");
11411
11412        long ident = Binder.clearCallingIdentity();
11413        try {
11414            Settings.Global.putInt(
11415                    mContext.getContentResolver(),
11416                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11417
11418            synchronized (this) {
11419                mLenientBackgroundCheck = enabled;
11420            }
11421        } finally {
11422            Binder.restoreCallingIdentity(ident);
11423        }
11424    }
11425
11426    @Override
11427    public void setActivityController(IActivityController controller) {
11428        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11429                "setActivityController()");
11430        synchronized (this) {
11431            mController = controller;
11432            Watchdog.getInstance().setActivityController(controller);
11433        }
11434    }
11435
11436    @Override
11437    public void setUserIsMonkey(boolean userIsMonkey) {
11438        synchronized (this) {
11439            synchronized (mPidsSelfLocked) {
11440                final int callingPid = Binder.getCallingPid();
11441                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11442                if (precessRecord == null) {
11443                    throw new SecurityException("Unknown process: " + callingPid);
11444                }
11445                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11446                    throw new SecurityException("Only an instrumentation process "
11447                            + "with a UiAutomation can call setUserIsMonkey");
11448                }
11449            }
11450            mUserIsMonkey = userIsMonkey;
11451        }
11452    }
11453
11454    @Override
11455    public boolean isUserAMonkey() {
11456        synchronized (this) {
11457            // If there is a controller also implies the user is a monkey.
11458            return (mUserIsMonkey || mController != null);
11459        }
11460    }
11461
11462    public void requestBugReport(int bugreportType) {
11463        String service = null;
11464        switch (bugreportType) {
11465            case ActivityManager.BUGREPORT_OPTION_FULL:
11466                service = "bugreport";
11467                break;
11468            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11469                service = "bugreportplus";
11470                break;
11471            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11472                service = "bugreportremote";
11473                break;
11474        }
11475        if (service == null) {
11476            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11477                    + bugreportType);
11478        }
11479        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11480        SystemProperties.set("ctl.start", service);
11481    }
11482
11483    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11484        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11485    }
11486
11487    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11488        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11489            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11490        }
11491        return KEY_DISPATCHING_TIMEOUT;
11492    }
11493
11494    @Override
11495    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11496        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11497                != PackageManager.PERMISSION_GRANTED) {
11498            throw new SecurityException("Requires permission "
11499                    + android.Manifest.permission.FILTER_EVENTS);
11500        }
11501        ProcessRecord proc;
11502        long timeout;
11503        synchronized (this) {
11504            synchronized (mPidsSelfLocked) {
11505                proc = mPidsSelfLocked.get(pid);
11506            }
11507            timeout = getInputDispatchingTimeoutLocked(proc);
11508        }
11509
11510        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11511            return -1;
11512        }
11513
11514        return timeout;
11515    }
11516
11517    /**
11518     * Handle input dispatching timeouts.
11519     * Returns whether input dispatching should be aborted or not.
11520     */
11521    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11522            final ActivityRecord activity, final ActivityRecord parent,
11523            final boolean aboveSystem, String reason) {
11524        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11525                != PackageManager.PERMISSION_GRANTED) {
11526            throw new SecurityException("Requires permission "
11527                    + android.Manifest.permission.FILTER_EVENTS);
11528        }
11529
11530        final String annotation;
11531        if (reason == null) {
11532            annotation = "Input dispatching timed out";
11533        } else {
11534            annotation = "Input dispatching timed out (" + reason + ")";
11535        }
11536
11537        if (proc != null) {
11538            synchronized (this) {
11539                if (proc.debugging) {
11540                    return false;
11541                }
11542
11543                if (mDidDexOpt) {
11544                    // Give more time since we were dexopting.
11545                    mDidDexOpt = false;
11546                    return false;
11547                }
11548
11549                if (proc.instrumentationClass != null) {
11550                    Bundle info = new Bundle();
11551                    info.putString("shortMsg", "keyDispatchingTimedOut");
11552                    info.putString("longMsg", annotation);
11553                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11554                    return true;
11555                }
11556            }
11557            mHandler.post(new Runnable() {
11558                @Override
11559                public void run() {
11560                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11561                }
11562            });
11563        }
11564
11565        return true;
11566    }
11567
11568    @Override
11569    public Bundle getAssistContextExtras(int requestType) {
11570        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11571                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11572        if (pae == null) {
11573            return null;
11574        }
11575        synchronized (pae) {
11576            while (!pae.haveResult) {
11577                try {
11578                    pae.wait();
11579                } catch (InterruptedException e) {
11580                }
11581            }
11582        }
11583        synchronized (this) {
11584            buildAssistBundleLocked(pae, pae.result);
11585            mPendingAssistExtras.remove(pae);
11586            mUiHandler.removeCallbacks(pae);
11587        }
11588        return pae.extras;
11589    }
11590
11591    @Override
11592    public boolean isAssistDataAllowedOnCurrentActivity() {
11593        int userId;
11594        synchronized (this) {
11595            userId = mUserController.getCurrentUserIdLocked();
11596            ActivityRecord activity = getFocusedStack().topActivity();
11597            if (activity == null) {
11598                return false;
11599            }
11600            userId = activity.userId;
11601        }
11602        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11603                Context.DEVICE_POLICY_SERVICE);
11604        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11605    }
11606
11607    @Override
11608    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11609        long ident = Binder.clearCallingIdentity();
11610        try {
11611            synchronized (this) {
11612                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11613                ActivityRecord top = getFocusedStack().topActivity();
11614                if (top != caller) {
11615                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11616                            + " is not current top " + top);
11617                    return false;
11618                }
11619                if (!top.nowVisible) {
11620                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11621                            + " is not visible");
11622                    return false;
11623                }
11624            }
11625            AssistUtils utils = new AssistUtils(mContext);
11626            return utils.showSessionForActiveService(args,
11627                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11628        } finally {
11629            Binder.restoreCallingIdentity(ident);
11630        }
11631    }
11632
11633    @Override
11634    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11635            IBinder activityToken) {
11636        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11637                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11638    }
11639
11640    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11641            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11642            long timeout) {
11643        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11644                "enqueueAssistContext()");
11645        synchronized (this) {
11646            ActivityRecord activity = getFocusedStack().topActivity();
11647            if (activity == null) {
11648                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11649                return null;
11650            }
11651            if (activity.app == null || activity.app.thread == null) {
11652                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11653                return null;
11654            }
11655            if (activityToken != null) {
11656                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11657                if (activity != caller) {
11658                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11659                            + " is not current top " + activity);
11660                    return null;
11661                }
11662            }
11663            PendingAssistExtras pae;
11664            Bundle extras = new Bundle();
11665            if (args != null) {
11666                extras.putAll(args);
11667            }
11668            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11669            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11670            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11671            try {
11672                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11673                        requestType);
11674                mPendingAssistExtras.add(pae);
11675                mUiHandler.postDelayed(pae, timeout);
11676            } catch (RemoteException e) {
11677                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11678                return null;
11679            }
11680            return pae;
11681        }
11682    }
11683
11684    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11685        IResultReceiver receiver;
11686        synchronized (this) {
11687            mPendingAssistExtras.remove(pae);
11688            receiver = pae.receiver;
11689        }
11690        if (receiver != null) {
11691            // Caller wants result sent back to them.
11692            try {
11693                pae.receiver.send(0, null);
11694            } catch (RemoteException e) {
11695            }
11696        }
11697    }
11698
11699    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11700        if (result != null) {
11701            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11702        }
11703        if (pae.hint != null) {
11704            pae.extras.putBoolean(pae.hint, true);
11705        }
11706    }
11707
11708    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11709            AssistContent content, Uri referrer) {
11710        PendingAssistExtras pae = (PendingAssistExtras)token;
11711        synchronized (pae) {
11712            pae.result = extras;
11713            pae.structure = structure;
11714            pae.content = content;
11715            if (referrer != null) {
11716                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11717            }
11718            pae.haveResult = true;
11719            pae.notifyAll();
11720            if (pae.intent == null && pae.receiver == null) {
11721                // Caller is just waiting for the result.
11722                return;
11723            }
11724        }
11725
11726        // We are now ready to launch the assist activity.
11727        IResultReceiver sendReceiver = null;
11728        Bundle sendBundle = null;
11729        synchronized (this) {
11730            buildAssistBundleLocked(pae, extras);
11731            boolean exists = mPendingAssistExtras.remove(pae);
11732            mUiHandler.removeCallbacks(pae);
11733            if (!exists) {
11734                // Timed out.
11735                return;
11736            }
11737            if ((sendReceiver=pae.receiver) != null) {
11738                // Caller wants result sent back to them.
11739                sendBundle = new Bundle();
11740                sendBundle.putBundle("data", pae.extras);
11741                sendBundle.putParcelable("structure", pae.structure);
11742                sendBundle.putParcelable("content", pae.content);
11743            }
11744        }
11745        if (sendReceiver != null) {
11746            try {
11747                sendReceiver.send(0, sendBundle);
11748            } catch (RemoteException e) {
11749            }
11750            return;
11751        }
11752
11753        long ident = Binder.clearCallingIdentity();
11754        try {
11755            pae.intent.replaceExtras(pae.extras);
11756            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11757                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11758                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11759            closeSystemDialogs("assist");
11760            try {
11761                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11762            } catch (ActivityNotFoundException e) {
11763                Slog.w(TAG, "No activity to handle assist action.", e);
11764            }
11765        } finally {
11766            Binder.restoreCallingIdentity(ident);
11767        }
11768    }
11769
11770    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11771            Bundle args) {
11772        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11773                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11774    }
11775
11776    public void registerProcessObserver(IProcessObserver observer) {
11777        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11778                "registerProcessObserver()");
11779        synchronized (this) {
11780            mProcessObservers.register(observer);
11781        }
11782    }
11783
11784    @Override
11785    public void unregisterProcessObserver(IProcessObserver observer) {
11786        synchronized (this) {
11787            mProcessObservers.unregister(observer);
11788        }
11789    }
11790
11791    @Override
11792    public void registerUidObserver(IUidObserver observer, int which) {
11793        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11794                "registerUidObserver()");
11795        synchronized (this) {
11796            mUidObservers.register(observer, which);
11797        }
11798    }
11799
11800    @Override
11801    public void unregisterUidObserver(IUidObserver observer) {
11802        synchronized (this) {
11803            mUidObservers.unregister(observer);
11804        }
11805    }
11806
11807    @Override
11808    public boolean convertFromTranslucent(IBinder token) {
11809        final long origId = Binder.clearCallingIdentity();
11810        try {
11811            synchronized (this) {
11812                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11813                if (r == null) {
11814                    return false;
11815                }
11816                final boolean translucentChanged = r.changeWindowTranslucency(true);
11817                if (translucentChanged) {
11818                    r.task.stack.releaseBackgroundResources(r);
11819                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11820                }
11821                mWindowManager.setAppFullscreen(token, true);
11822                return translucentChanged;
11823            }
11824        } finally {
11825            Binder.restoreCallingIdentity(origId);
11826        }
11827    }
11828
11829    @Override
11830    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11831        final long origId = Binder.clearCallingIdentity();
11832        try {
11833            synchronized (this) {
11834                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11835                if (r == null) {
11836                    return false;
11837                }
11838                int index = r.task.mActivities.lastIndexOf(r);
11839                if (index > 0) {
11840                    ActivityRecord under = r.task.mActivities.get(index - 1);
11841                    under.returningOptions = options;
11842                }
11843                final boolean translucentChanged = r.changeWindowTranslucency(false);
11844                if (translucentChanged) {
11845                    r.task.stack.convertActivityToTranslucent(r);
11846                }
11847                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11848                mWindowManager.setAppFullscreen(token, false);
11849                return translucentChanged;
11850            }
11851        } finally {
11852            Binder.restoreCallingIdentity(origId);
11853        }
11854    }
11855
11856    @Override
11857    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11858        final long origId = Binder.clearCallingIdentity();
11859        try {
11860            synchronized (this) {
11861                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11862                if (r != null) {
11863                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11864                }
11865            }
11866            return false;
11867        } finally {
11868            Binder.restoreCallingIdentity(origId);
11869        }
11870    }
11871
11872    @Override
11873    public boolean isBackgroundVisibleBehind(IBinder token) {
11874        final long origId = Binder.clearCallingIdentity();
11875        try {
11876            synchronized (this) {
11877                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11878                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11879                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11880                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11881                return visible;
11882            }
11883        } finally {
11884            Binder.restoreCallingIdentity(origId);
11885        }
11886    }
11887
11888    @Override
11889    public ActivityOptions getActivityOptions(IBinder token) {
11890        final long origId = Binder.clearCallingIdentity();
11891        try {
11892            synchronized (this) {
11893                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11894                if (r != null) {
11895                    final ActivityOptions activityOptions = r.pendingOptions;
11896                    r.pendingOptions = null;
11897                    return activityOptions;
11898                }
11899                return null;
11900            }
11901        } finally {
11902            Binder.restoreCallingIdentity(origId);
11903        }
11904    }
11905
11906    @Override
11907    public void setImmersive(IBinder token, boolean immersive) {
11908        synchronized(this) {
11909            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11910            if (r == null) {
11911                throw new IllegalArgumentException();
11912            }
11913            r.immersive = immersive;
11914
11915            // update associated state if we're frontmost
11916            if (r == mFocusedActivity) {
11917                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11918                applyUpdateLockStateLocked(r);
11919            }
11920        }
11921    }
11922
11923    @Override
11924    public boolean isImmersive(IBinder token) {
11925        synchronized (this) {
11926            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11927            if (r == null) {
11928                throw new IllegalArgumentException();
11929            }
11930            return r.immersive;
11931        }
11932    }
11933
11934    @Override
11935    public void setVrMode(IBinder token, boolean enabled) {
11936        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11937            throw new UnsupportedOperationException("VR mode not supported on this device!");
11938        }
11939
11940        synchronized(this) {
11941            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11942            if (r == null) {
11943                throw new IllegalArgumentException();
11944            }
11945            r.isVrActivity = enabled;
11946
11947            // Update associated state if this activity is currently focused
11948            if (r == mFocusedActivity) {
11949                applyUpdateVrModeLocked(r);
11950            }
11951        }
11952    }
11953
11954    public boolean isTopActivityImmersive() {
11955        enforceNotIsolatedCaller("startActivity");
11956        synchronized (this) {
11957            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11958            return (r != null) ? r.immersive : false;
11959        }
11960    }
11961
11962    @Override
11963    public boolean isTopOfTask(IBinder token) {
11964        synchronized (this) {
11965            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11966            if (r == null) {
11967                throw new IllegalArgumentException();
11968            }
11969            return r.task.getTopActivity() == r;
11970        }
11971    }
11972
11973    public final void enterSafeMode() {
11974        synchronized(this) {
11975            // It only makes sense to do this before the system is ready
11976            // and started launching other packages.
11977            if (!mSystemReady) {
11978                try {
11979                    AppGlobals.getPackageManager().enterSafeMode();
11980                } catch (RemoteException e) {
11981                }
11982            }
11983
11984            mSafeMode = true;
11985        }
11986    }
11987
11988    public final void showSafeModeOverlay() {
11989        View v = LayoutInflater.from(mContext).inflate(
11990                com.android.internal.R.layout.safe_mode, null);
11991        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11992        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11993        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11994        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11995        lp.gravity = Gravity.BOTTOM | Gravity.START;
11996        lp.format = v.getBackground().getOpacity();
11997        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11998                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11999        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12000        ((WindowManager)mContext.getSystemService(
12001                Context.WINDOW_SERVICE)).addView(v, lp);
12002    }
12003
12004    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12005        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12006            return;
12007        }
12008        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12009        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12010        synchronized (stats) {
12011            if (mBatteryStatsService.isOnBattery()) {
12012                mBatteryStatsService.enforceCallingPermission();
12013                int MY_UID = Binder.getCallingUid();
12014                final int uid;
12015                if (sender == null) {
12016                    uid = sourceUid;
12017                } else {
12018                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12019                }
12020                BatteryStatsImpl.Uid.Pkg pkg =
12021                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12022                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12023                pkg.noteWakeupAlarmLocked(tag);
12024            }
12025        }
12026    }
12027
12028    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12029        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12030            return;
12031        }
12032        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12033        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12034        synchronized (stats) {
12035            mBatteryStatsService.enforceCallingPermission();
12036            int MY_UID = Binder.getCallingUid();
12037            final int uid;
12038            if (sender == null) {
12039                uid = sourceUid;
12040            } else {
12041                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12042            }
12043            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12044        }
12045    }
12046
12047    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12048        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12049            return;
12050        }
12051        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12052        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12053        synchronized (stats) {
12054            mBatteryStatsService.enforceCallingPermission();
12055            int MY_UID = Binder.getCallingUid();
12056            final int uid;
12057            if (sender == null) {
12058                uid = sourceUid;
12059            } else {
12060                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12061            }
12062            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12063        }
12064    }
12065
12066    public boolean killPids(int[] pids, String pReason, boolean secure) {
12067        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12068            throw new SecurityException("killPids only available to the system");
12069        }
12070        String reason = (pReason == null) ? "Unknown" : pReason;
12071        // XXX Note: don't acquire main activity lock here, because the window
12072        // manager calls in with its locks held.
12073
12074        boolean killed = false;
12075        synchronized (mPidsSelfLocked) {
12076            int worstType = 0;
12077            for (int i=0; i<pids.length; i++) {
12078                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12079                if (proc != null) {
12080                    int type = proc.setAdj;
12081                    if (type > worstType) {
12082                        worstType = type;
12083                    }
12084                }
12085            }
12086
12087            // If the worst oom_adj is somewhere in the cached proc LRU range,
12088            // then constrain it so we will kill all cached procs.
12089            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12090                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12091                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12092            }
12093
12094            // If this is not a secure call, don't let it kill processes that
12095            // are important.
12096            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12097                worstType = ProcessList.SERVICE_ADJ;
12098            }
12099
12100            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12101            for (int i=0; i<pids.length; i++) {
12102                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12103                if (proc == null) {
12104                    continue;
12105                }
12106                int adj = proc.setAdj;
12107                if (adj >= worstType && !proc.killedByAm) {
12108                    proc.kill(reason, true);
12109                    killed = true;
12110                }
12111            }
12112        }
12113        return killed;
12114    }
12115
12116    @Override
12117    public void killUid(int appId, int userId, String reason) {
12118        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12119        synchronized (this) {
12120            final long identity = Binder.clearCallingIdentity();
12121            try {
12122                killPackageProcessesLocked(null, appId, userId,
12123                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12124                        reason != null ? reason : "kill uid");
12125            } finally {
12126                Binder.restoreCallingIdentity(identity);
12127            }
12128        }
12129    }
12130
12131    @Override
12132    public boolean killProcessesBelowForeground(String reason) {
12133        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12134            throw new SecurityException("killProcessesBelowForeground() only available to system");
12135        }
12136
12137        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12138    }
12139
12140    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12141        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12142            throw new SecurityException("killProcessesBelowAdj() only available to system");
12143        }
12144
12145        boolean killed = false;
12146        synchronized (mPidsSelfLocked) {
12147            final int size = mPidsSelfLocked.size();
12148            for (int i = 0; i < size; i++) {
12149                final int pid = mPidsSelfLocked.keyAt(i);
12150                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12151                if (proc == null) continue;
12152
12153                final int adj = proc.setAdj;
12154                if (adj > belowAdj && !proc.killedByAm) {
12155                    proc.kill(reason, true);
12156                    killed = true;
12157                }
12158            }
12159        }
12160        return killed;
12161    }
12162
12163    @Override
12164    public void hang(final IBinder who, boolean allowRestart) {
12165        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12166                != PackageManager.PERMISSION_GRANTED) {
12167            throw new SecurityException("Requires permission "
12168                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12169        }
12170
12171        final IBinder.DeathRecipient death = new DeathRecipient() {
12172            @Override
12173            public void binderDied() {
12174                synchronized (this) {
12175                    notifyAll();
12176                }
12177            }
12178        };
12179
12180        try {
12181            who.linkToDeath(death, 0);
12182        } catch (RemoteException e) {
12183            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12184            return;
12185        }
12186
12187        synchronized (this) {
12188            Watchdog.getInstance().setAllowRestart(allowRestart);
12189            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12190            synchronized (death) {
12191                while (who.isBinderAlive()) {
12192                    try {
12193                        death.wait();
12194                    } catch (InterruptedException e) {
12195                    }
12196                }
12197            }
12198            Watchdog.getInstance().setAllowRestart(true);
12199        }
12200    }
12201
12202    @Override
12203    public void restart() {
12204        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12205                != PackageManager.PERMISSION_GRANTED) {
12206            throw new SecurityException("Requires permission "
12207                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12208        }
12209
12210        Log.i(TAG, "Sending shutdown broadcast...");
12211
12212        BroadcastReceiver br = new BroadcastReceiver() {
12213            @Override public void onReceive(Context context, Intent intent) {
12214                // Now the broadcast is done, finish up the low-level shutdown.
12215                Log.i(TAG, "Shutting down activity manager...");
12216                shutdown(10000);
12217                Log.i(TAG, "Shutdown complete, restarting!");
12218                Process.killProcess(Process.myPid());
12219                System.exit(10);
12220            }
12221        };
12222
12223        // First send the high-level shut down broadcast.
12224        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12225        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12226        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12227        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12228        mContext.sendOrderedBroadcastAsUser(intent,
12229                UserHandle.ALL, null, br, mHandler, 0, null, null);
12230        */
12231        br.onReceive(mContext, intent);
12232    }
12233
12234    private long getLowRamTimeSinceIdle(long now) {
12235        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12236    }
12237
12238    @Override
12239    public void performIdleMaintenance() {
12240        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12241                != PackageManager.PERMISSION_GRANTED) {
12242            throw new SecurityException("Requires permission "
12243                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12244        }
12245
12246        synchronized (this) {
12247            final long now = SystemClock.uptimeMillis();
12248            final long timeSinceLastIdle = now - mLastIdleTime;
12249            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12250            mLastIdleTime = now;
12251            mLowRamTimeSinceLastIdle = 0;
12252            if (mLowRamStartTime != 0) {
12253                mLowRamStartTime = now;
12254            }
12255
12256            StringBuilder sb = new StringBuilder(128);
12257            sb.append("Idle maintenance over ");
12258            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12259            sb.append(" low RAM for ");
12260            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12261            Slog.i(TAG, sb.toString());
12262
12263            // If at least 1/3 of our time since the last idle period has been spent
12264            // with RAM low, then we want to kill processes.
12265            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12266
12267            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12268                ProcessRecord proc = mLruProcesses.get(i);
12269                if (proc.notCachedSinceIdle) {
12270                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12271                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12272                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12273                        if (doKilling && proc.initialIdlePss != 0
12274                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12275                            sb = new StringBuilder(128);
12276                            sb.append("Kill");
12277                            sb.append(proc.processName);
12278                            sb.append(" in idle maint: pss=");
12279                            sb.append(proc.lastPss);
12280                            sb.append(", swapPss=");
12281                            sb.append(proc.lastSwapPss);
12282                            sb.append(", initialPss=");
12283                            sb.append(proc.initialIdlePss);
12284                            sb.append(", period=");
12285                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12286                            sb.append(", lowRamPeriod=");
12287                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12288                            Slog.wtfQuiet(TAG, sb.toString());
12289                            proc.kill("idle maint (pss " + proc.lastPss
12290                                    + " from " + proc.initialIdlePss + ")", true);
12291                        }
12292                    }
12293                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12294                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12295                    proc.notCachedSinceIdle = true;
12296                    proc.initialIdlePss = 0;
12297                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12298                            mTestPssMode, isSleeping(), now);
12299                }
12300            }
12301
12302            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12303            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12304        }
12305    }
12306
12307    private void retrieveSettings() {
12308        final ContentResolver resolver = mContext.getContentResolver();
12309        final boolean freeformWindowManagement =
12310                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12311                        || Settings.Global.getInt(
12312                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12313        final boolean supportsPictureInPicture =
12314                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12315
12316        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12317        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12318        final boolean alwaysFinishActivities =
12319                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12320        final boolean lenientBackgroundCheck =
12321                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12322        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12323        final boolean forceResizable = Settings.Global.getInt(
12324                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12325        // Transfer any global setting for forcing RTL layout, into a System Property
12326        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12327
12328        final Configuration configuration = new Configuration();
12329        Settings.System.getConfiguration(resolver, configuration);
12330        if (forceRtl) {
12331            // This will take care of setting the correct layout direction flags
12332            configuration.setLayoutDirection(configuration.locale);
12333        }
12334
12335        synchronized (this) {
12336            mDebugApp = mOrigDebugApp = debugApp;
12337            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12338            mAlwaysFinishActivities = alwaysFinishActivities;
12339            mLenientBackgroundCheck = lenientBackgroundCheck;
12340            mForceResizableActivities = forceResizable;
12341            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12342            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12343            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12344            // This happens before any activities are started, so we can
12345            // change mConfiguration in-place.
12346            updateConfigurationLocked(configuration, null, true);
12347            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12348                    "Initial config: " + mConfiguration);
12349
12350            // Load resources only after the current configuration has been set.
12351            final Resources res = mContext.getResources();
12352            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12353            mThumbnailWidth = res.getDimensionPixelSize(
12354                    com.android.internal.R.dimen.thumbnail_width);
12355            mThumbnailHeight = res.getDimensionPixelSize(
12356                    com.android.internal.R.dimen.thumbnail_height);
12357            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12358                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12359            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12360                    com.android.internal.R.string.config_appsNotReportingCrashes));
12361        }
12362    }
12363
12364    public boolean testIsSystemReady() {
12365        // no need to synchronize(this) just to read & return the value
12366        return mSystemReady;
12367    }
12368
12369    private static File getCalledPreBootReceiversFile() {
12370        File dataDir = Environment.getDataDirectory();
12371        File systemDir = new File(dataDir, "system");
12372        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12373        return fname;
12374    }
12375
12376    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12377        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12378        File file = getCalledPreBootReceiversFile();
12379        FileInputStream fis = null;
12380        try {
12381            fis = new FileInputStream(file);
12382            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12383            int fvers = dis.readInt();
12384            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12385                String vers = dis.readUTF();
12386                String codename = dis.readUTF();
12387                String build = dis.readUTF();
12388                if (android.os.Build.VERSION.RELEASE.equals(vers)
12389                        && android.os.Build.VERSION.CODENAME.equals(codename)
12390                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12391                    int num = dis.readInt();
12392                    while (num > 0) {
12393                        num--;
12394                        String pkg = dis.readUTF();
12395                        String cls = dis.readUTF();
12396                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12397                    }
12398                }
12399            }
12400        } catch (FileNotFoundException e) {
12401        } catch (IOException e) {
12402            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12403        } finally {
12404            if (fis != null) {
12405                try {
12406                    fis.close();
12407                } catch (IOException e) {
12408                }
12409            }
12410        }
12411        return lastDoneReceivers;
12412    }
12413
12414    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12415        File file = getCalledPreBootReceiversFile();
12416        FileOutputStream fos = null;
12417        DataOutputStream dos = null;
12418        try {
12419            fos = new FileOutputStream(file);
12420            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12421            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12422            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12423            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12424            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12425            dos.writeInt(list.size());
12426            for (int i=0; i<list.size(); i++) {
12427                dos.writeUTF(list.get(i).getPackageName());
12428                dos.writeUTF(list.get(i).getClassName());
12429            }
12430        } catch (IOException e) {
12431            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12432            file.delete();
12433        } finally {
12434            FileUtils.sync(fos);
12435            if (dos != null) {
12436                try {
12437                    dos.close();
12438                } catch (IOException e) {
12439                    // TODO Auto-generated catch block
12440                    e.printStackTrace();
12441                }
12442            }
12443        }
12444    }
12445
12446    final class PreBootContinuation extends IIntentReceiver.Stub {
12447        final Intent intent;
12448        final Runnable onFinishCallback;
12449        final ArrayList<ComponentName> doneReceivers;
12450        final List<ResolveInfo> ris;
12451        final int[] users;
12452        int lastRi = -1;
12453        int curRi = 0;
12454        int curUser = 0;
12455
12456        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12457                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12458            intent = _intent;
12459            onFinishCallback = _onFinishCallback;
12460            doneReceivers = _doneReceivers;
12461            ris = _ris;
12462            users = _users;
12463        }
12464
12465        void go() {
12466            if (lastRi != curRi) {
12467                ActivityInfo ai = ris.get(curRi).activityInfo;
12468                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12469                intent.setComponent(comp);
12470                doneReceivers.add(comp);
12471                lastRi = curRi;
12472                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12473                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12474            }
12475            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12476                    + " for user " + users[curUser]);
12477            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12478            broadcastIntentLocked(null, null, intent, null, this,
12479                    0, null, null, null, AppOpsManager.OP_NONE,
12480                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12481        }
12482
12483        public void performReceive(Intent intent, int resultCode,
12484                String data, Bundle extras, boolean ordered,
12485                boolean sticky, int sendingUser) {
12486            curUser++;
12487            if (curUser >= users.length) {
12488                curUser = 0;
12489                curRi++;
12490                if (curRi >= ris.size()) {
12491                    // All done sending broadcasts!
12492                    if (onFinishCallback != null) {
12493                        // The raw IIntentReceiver interface is called
12494                        // with the AM lock held, so redispatch to
12495                        // execute our code without the lock.
12496                        mHandler.post(onFinishCallback);
12497                    }
12498                    return;
12499                }
12500            }
12501            go();
12502        }
12503    }
12504
12505    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12506            ArrayList<ComponentName> doneReceivers) {
12507        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12508        List<ResolveInfo> ris = null;
12509        try {
12510            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12511                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
12512        } catch (RemoteException e) {
12513        }
12514        if (ris == null) {
12515            return false;
12516        }
12517        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12518
12519        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12520        for (int i=0; i<ris.size(); i++) {
12521            ActivityInfo ai = ris.get(i).activityInfo;
12522            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12523            if (lastDoneReceivers.contains(comp)) {
12524                // We already did the pre boot receiver for this app with the current
12525                // platform version, so don't do it again...
12526                ris.remove(i);
12527                i--;
12528                // ...however, do keep it as one that has been done, so we don't
12529                // forget about it when rewriting the file of last done receivers.
12530                doneReceivers.add(comp);
12531            }
12532        }
12533
12534        if (ris.size() <= 0) {
12535            return false;
12536        }
12537
12538        // TODO: can we still do this with per user encryption?
12539        final int[] users = mUserController.getUsers();
12540        if (users.length <= 0) {
12541            return false;
12542        }
12543
12544        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12545                ris, users);
12546        cont.go();
12547        return true;
12548    }
12549
12550    public void systemReady(final Runnable goingCallback) {
12551        synchronized(this) {
12552            if (mSystemReady) {
12553                // If we're done calling all the receivers, run the next "boot phase" passed in
12554                // by the SystemServer
12555                if (goingCallback != null) {
12556                    goingCallback.run();
12557                }
12558                return;
12559            }
12560
12561            mLocalDeviceIdleController
12562                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12563
12564            // Make sure we have the current profile info, since it is needed for security checks.
12565            mUserController.onSystemReady();
12566
12567            mRecentTasks.onSystemReadyLocked();
12568            // Check to see if there are any update receivers to run.
12569            if (!mDidUpdate) {
12570                if (mWaitingUpdate) {
12571                    return;
12572                }
12573                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12574                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12575                    public void run() {
12576                        synchronized (ActivityManagerService.this) {
12577                            mDidUpdate = true;
12578                        }
12579                        showBootMessage(mContext.getText(
12580                                R.string.android_upgrading_complete),
12581                                false);
12582                        writeLastDonePreBootReceivers(doneReceivers);
12583                        systemReady(goingCallback);
12584                    }
12585                }, doneReceivers);
12586
12587                if (mWaitingUpdate) {
12588                    return;
12589                }
12590                mDidUpdate = true;
12591            }
12592
12593            mAppOpsService.systemReady();
12594            mSystemReady = true;
12595        }
12596
12597        ArrayList<ProcessRecord> procsToKill = null;
12598        synchronized(mPidsSelfLocked) {
12599            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12600                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12601                if (!isAllowedWhileBooting(proc.info)){
12602                    if (procsToKill == null) {
12603                        procsToKill = new ArrayList<ProcessRecord>();
12604                    }
12605                    procsToKill.add(proc);
12606                }
12607            }
12608        }
12609
12610        synchronized(this) {
12611            if (procsToKill != null) {
12612                for (int i=procsToKill.size()-1; i>=0; i--) {
12613                    ProcessRecord proc = procsToKill.get(i);
12614                    Slog.i(TAG, "Removing system update proc: " + proc);
12615                    removeProcessLocked(proc, true, false, "system update done");
12616                }
12617            }
12618
12619            // Now that we have cleaned up any update processes, we
12620            // are ready to start launching real processes and know that
12621            // we won't trample on them any more.
12622            mProcessesReady = true;
12623        }
12624
12625        Slog.i(TAG, "System now ready");
12626        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12627            SystemClock.uptimeMillis());
12628
12629        synchronized(this) {
12630            // Make sure we have no pre-ready processes sitting around.
12631
12632            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12633                ResolveInfo ri = mContext.getPackageManager()
12634                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12635                                STOCK_PM_FLAGS);
12636                CharSequence errorMsg = null;
12637                if (ri != null) {
12638                    ActivityInfo ai = ri.activityInfo;
12639                    ApplicationInfo app = ai.applicationInfo;
12640                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12641                        mTopAction = Intent.ACTION_FACTORY_TEST;
12642                        mTopData = null;
12643                        mTopComponent = new ComponentName(app.packageName,
12644                                ai.name);
12645                    } else {
12646                        errorMsg = mContext.getResources().getText(
12647                                com.android.internal.R.string.factorytest_not_system);
12648                    }
12649                } else {
12650                    errorMsg = mContext.getResources().getText(
12651                            com.android.internal.R.string.factorytest_no_action);
12652                }
12653                if (errorMsg != null) {
12654                    mTopAction = null;
12655                    mTopData = null;
12656                    mTopComponent = null;
12657                    Message msg = Message.obtain();
12658                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12659                    msg.getData().putCharSequence("msg", errorMsg);
12660                    mUiHandler.sendMessage(msg);
12661                }
12662            }
12663        }
12664
12665        retrieveSettings();
12666        final int currentUserId;
12667        synchronized (this) {
12668            currentUserId = mUserController.getCurrentUserIdLocked();
12669            readGrantedUriPermissionsLocked();
12670        }
12671
12672        if (goingCallback != null) goingCallback.run();
12673
12674        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12675                Integer.toString(currentUserId), currentUserId);
12676        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12677                Integer.toString(currentUserId), currentUserId);
12678        mSystemServiceManager.startUser(currentUserId);
12679
12680        synchronized (this) {
12681            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12682                try {
12683                    List apps = AppGlobals.getPackageManager().
12684                        getPersistentApplications(STOCK_PM_FLAGS);
12685                    if (apps != null) {
12686                        int N = apps.size();
12687                        int i;
12688                        for (i=0; i<N; i++) {
12689                            ApplicationInfo info
12690                                = (ApplicationInfo)apps.get(i);
12691                            if (info != null &&
12692                                    !info.packageName.equals("android")) {
12693                                addAppLocked(info, false, null /* ABI override */);
12694                            }
12695                        }
12696                    }
12697                } catch (RemoteException ex) {
12698                    // pm is in same process, this will never happen.
12699                }
12700            }
12701
12702            // Start up initial activity.
12703            mBooting = true;
12704            // Enable home activity for system user, so that the system can always boot
12705            if (UserManager.isSplitSystemUser()) {
12706                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12707                try {
12708                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12709                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12710                            UserHandle.USER_SYSTEM);
12711                } catch (RemoteException e) {
12712                    throw e.rethrowAsRuntimeException();
12713                }
12714            }
12715            startHomeActivityLocked(currentUserId, "systemReady");
12716
12717            try {
12718                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12719                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12720                            + " data partition or your device will be unstable.");
12721                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12722                }
12723            } catch (RemoteException e) {
12724            }
12725
12726            if (!Build.isBuildConsistent()) {
12727                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12728                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12729            }
12730
12731            long ident = Binder.clearCallingIdentity();
12732            try {
12733                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12734                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12735                        | Intent.FLAG_RECEIVER_FOREGROUND);
12736                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12737                broadcastIntentLocked(null, null, intent,
12738                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12739                        null, false, false, MY_PID, Process.SYSTEM_UID,
12740                        currentUserId);
12741                intent = new Intent(Intent.ACTION_USER_STARTING);
12742                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12743                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12744                broadcastIntentLocked(null, null, intent,
12745                        null, new IIntentReceiver.Stub() {
12746                            @Override
12747                            public void performReceive(Intent intent, int resultCode, String data,
12748                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12749                                    throws RemoteException {
12750                            }
12751                        }, 0, null, null,
12752                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12753                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12754            } catch (Throwable t) {
12755                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12756            } finally {
12757                Binder.restoreCallingIdentity(ident);
12758            }
12759            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12760            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12761        }
12762    }
12763
12764    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12765        synchronized (this) {
12766            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12767        }
12768    }
12769
12770    void skipCurrentReceiverLocked(ProcessRecord app) {
12771        for (BroadcastQueue queue : mBroadcastQueues) {
12772            queue.skipCurrentReceiverLocked(app);
12773        }
12774    }
12775
12776    /**
12777     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12778     * The application process will exit immediately after this call returns.
12779     * @param app object of the crashing app, null for the system server
12780     * @param crashInfo describing the exception
12781     */
12782    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12783        ProcessRecord r = findAppProcess(app, "Crash");
12784        final String processName = app == null ? "system_server"
12785                : (r == null ? "unknown" : r.processName);
12786
12787        handleApplicationCrashInner("crash", r, processName, crashInfo);
12788    }
12789
12790    /* Native crash reporting uses this inner version because it needs to be somewhat
12791     * decoupled from the AM-managed cleanup lifecycle
12792     */
12793    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12794            ApplicationErrorReport.CrashInfo crashInfo) {
12795        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12796                UserHandle.getUserId(Binder.getCallingUid()), processName,
12797                r == null ? -1 : r.info.flags,
12798                crashInfo.exceptionClassName,
12799                crashInfo.exceptionMessage,
12800                crashInfo.throwFileName,
12801                crashInfo.throwLineNumber);
12802
12803        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12804
12805        mAppErrors.crashApplication(r, crashInfo);
12806    }
12807
12808    public void handleApplicationStrictModeViolation(
12809            IBinder app,
12810            int violationMask,
12811            StrictMode.ViolationInfo info) {
12812        ProcessRecord r = findAppProcess(app, "StrictMode");
12813        if (r == null) {
12814            return;
12815        }
12816
12817        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12818            Integer stackFingerprint = info.hashCode();
12819            boolean logIt = true;
12820            synchronized (mAlreadyLoggedViolatedStacks) {
12821                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12822                    logIt = false;
12823                    // TODO: sub-sample into EventLog for these, with
12824                    // the info.durationMillis?  Then we'd get
12825                    // the relative pain numbers, without logging all
12826                    // the stack traces repeatedly.  We'd want to do
12827                    // likewise in the client code, which also does
12828                    // dup suppression, before the Binder call.
12829                } else {
12830                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12831                        mAlreadyLoggedViolatedStacks.clear();
12832                    }
12833                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12834                }
12835            }
12836            if (logIt) {
12837                logStrictModeViolationToDropBox(r, info);
12838            }
12839        }
12840
12841        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12842            AppErrorResult result = new AppErrorResult();
12843            synchronized (this) {
12844                final long origId = Binder.clearCallingIdentity();
12845
12846                Message msg = Message.obtain();
12847                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12848                HashMap<String, Object> data = new HashMap<String, Object>();
12849                data.put("result", result);
12850                data.put("app", r);
12851                data.put("violationMask", violationMask);
12852                data.put("info", info);
12853                msg.obj = data;
12854                mUiHandler.sendMessage(msg);
12855
12856                Binder.restoreCallingIdentity(origId);
12857            }
12858            int res = result.get();
12859            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12860        }
12861    }
12862
12863    // Depending on the policy in effect, there could be a bunch of
12864    // these in quick succession so we try to batch these together to
12865    // minimize disk writes, number of dropbox entries, and maximize
12866    // compression, by having more fewer, larger records.
12867    private void logStrictModeViolationToDropBox(
12868            ProcessRecord process,
12869            StrictMode.ViolationInfo info) {
12870        if (info == null) {
12871            return;
12872        }
12873        final boolean isSystemApp = process == null ||
12874                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12875                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12876        final String processName = process == null ? "unknown" : process.processName;
12877        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12878        final DropBoxManager dbox = (DropBoxManager)
12879                mContext.getSystemService(Context.DROPBOX_SERVICE);
12880
12881        // Exit early if the dropbox isn't configured to accept this report type.
12882        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12883
12884        boolean bufferWasEmpty;
12885        boolean needsFlush;
12886        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12887        synchronized (sb) {
12888            bufferWasEmpty = sb.length() == 0;
12889            appendDropBoxProcessHeaders(process, processName, sb);
12890            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12891            sb.append("System-App: ").append(isSystemApp).append("\n");
12892            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12893            if (info.violationNumThisLoop != 0) {
12894                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12895            }
12896            if (info.numAnimationsRunning != 0) {
12897                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12898            }
12899            if (info.broadcastIntentAction != null) {
12900                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12901            }
12902            if (info.durationMillis != -1) {
12903                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12904            }
12905            if (info.numInstances != -1) {
12906                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12907            }
12908            if (info.tags != null) {
12909                for (String tag : info.tags) {
12910                    sb.append("Span-Tag: ").append(tag).append("\n");
12911                }
12912            }
12913            sb.append("\n");
12914            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12915                sb.append(info.crashInfo.stackTrace);
12916                sb.append("\n");
12917            }
12918            if (info.message != null) {
12919                sb.append(info.message);
12920                sb.append("\n");
12921            }
12922
12923            // Only buffer up to ~64k.  Various logging bits truncate
12924            // things at 128k.
12925            needsFlush = (sb.length() > 64 * 1024);
12926        }
12927
12928        // Flush immediately if the buffer's grown too large, or this
12929        // is a non-system app.  Non-system apps are isolated with a
12930        // different tag & policy and not batched.
12931        //
12932        // Batching is useful during internal testing with
12933        // StrictMode settings turned up high.  Without batching,
12934        // thousands of separate files could be created on boot.
12935        if (!isSystemApp || needsFlush) {
12936            new Thread("Error dump: " + dropboxTag) {
12937                @Override
12938                public void run() {
12939                    String report;
12940                    synchronized (sb) {
12941                        report = sb.toString();
12942                        sb.delete(0, sb.length());
12943                        sb.trimToSize();
12944                    }
12945                    if (report.length() != 0) {
12946                        dbox.addText(dropboxTag, report);
12947                    }
12948                }
12949            }.start();
12950            return;
12951        }
12952
12953        // System app batching:
12954        if (!bufferWasEmpty) {
12955            // An existing dropbox-writing thread is outstanding, so
12956            // we don't need to start it up.  The existing thread will
12957            // catch the buffer appends we just did.
12958            return;
12959        }
12960
12961        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12962        // (After this point, we shouldn't access AMS internal data structures.)
12963        new Thread("Error dump: " + dropboxTag) {
12964            @Override
12965            public void run() {
12966                // 5 second sleep to let stacks arrive and be batched together
12967                try {
12968                    Thread.sleep(5000);  // 5 seconds
12969                } catch (InterruptedException e) {}
12970
12971                String errorReport;
12972                synchronized (mStrictModeBuffer) {
12973                    errorReport = mStrictModeBuffer.toString();
12974                    if (errorReport.length() == 0) {
12975                        return;
12976                    }
12977                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12978                    mStrictModeBuffer.trimToSize();
12979                }
12980                dbox.addText(dropboxTag, errorReport);
12981            }
12982        }.start();
12983    }
12984
12985    /**
12986     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12987     * @param app object of the crashing app, null for the system server
12988     * @param tag reported by the caller
12989     * @param system whether this wtf is coming from the system
12990     * @param crashInfo describing the context of the error
12991     * @return true if the process should exit immediately (WTF is fatal)
12992     */
12993    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12994            final ApplicationErrorReport.CrashInfo crashInfo) {
12995        final int callingUid = Binder.getCallingUid();
12996        final int callingPid = Binder.getCallingPid();
12997
12998        if (system) {
12999            // If this is coming from the system, we could very well have low-level
13000            // system locks held, so we want to do this all asynchronously.  And we
13001            // never want this to become fatal, so there is that too.
13002            mHandler.post(new Runnable() {
13003                @Override public void run() {
13004                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13005                }
13006            });
13007            return false;
13008        }
13009
13010        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13011                crashInfo);
13012
13013        if (r != null && r.pid != Process.myPid() &&
13014                Settings.Global.getInt(mContext.getContentResolver(),
13015                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13016            mAppErrors.crashApplication(r, crashInfo);
13017            return true;
13018        } else {
13019            return false;
13020        }
13021    }
13022
13023    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13024            final ApplicationErrorReport.CrashInfo crashInfo) {
13025        final ProcessRecord r = findAppProcess(app, "WTF");
13026        final String processName = app == null ? "system_server"
13027                : (r == null ? "unknown" : r.processName);
13028
13029        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13030                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13031
13032        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13033
13034        return r;
13035    }
13036
13037    /**
13038     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13039     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13040     */
13041    private ProcessRecord findAppProcess(IBinder app, String reason) {
13042        if (app == null) {
13043            return null;
13044        }
13045
13046        synchronized (this) {
13047            final int NP = mProcessNames.getMap().size();
13048            for (int ip=0; ip<NP; ip++) {
13049                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13050                final int NA = apps.size();
13051                for (int ia=0; ia<NA; ia++) {
13052                    ProcessRecord p = apps.valueAt(ia);
13053                    if (p.thread != null && p.thread.asBinder() == app) {
13054                        return p;
13055                    }
13056                }
13057            }
13058
13059            Slog.w(TAG, "Can't find mystery application for " + reason
13060                    + " from pid=" + Binder.getCallingPid()
13061                    + " uid=" + Binder.getCallingUid() + ": " + app);
13062            return null;
13063        }
13064    }
13065
13066    /**
13067     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13068     * to append various headers to the dropbox log text.
13069     */
13070    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13071            StringBuilder sb) {
13072        // Watchdog thread ends up invoking this function (with
13073        // a null ProcessRecord) to add the stack file to dropbox.
13074        // Do not acquire a lock on this (am) in such cases, as it
13075        // could cause a potential deadlock, if and when watchdog
13076        // is invoked due to unavailability of lock on am and it
13077        // would prevent watchdog from killing system_server.
13078        if (process == null) {
13079            sb.append("Process: ").append(processName).append("\n");
13080            return;
13081        }
13082        // Note: ProcessRecord 'process' is guarded by the service
13083        // instance.  (notably process.pkgList, which could otherwise change
13084        // concurrently during execution of this method)
13085        synchronized (this) {
13086            sb.append("Process: ").append(processName).append("\n");
13087            int flags = process.info.flags;
13088            IPackageManager pm = AppGlobals.getPackageManager();
13089            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13090            for (int ip=0; ip<process.pkgList.size(); ip++) {
13091                String pkg = process.pkgList.keyAt(ip);
13092                sb.append("Package: ").append(pkg);
13093                try {
13094                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13095                    if (pi != null) {
13096                        sb.append(" v").append(pi.versionCode);
13097                        if (pi.versionName != null) {
13098                            sb.append(" (").append(pi.versionName).append(")");
13099                        }
13100                    }
13101                } catch (RemoteException e) {
13102                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13103                }
13104                sb.append("\n");
13105            }
13106        }
13107    }
13108
13109    private static String processClass(ProcessRecord process) {
13110        if (process == null || process.pid == MY_PID) {
13111            return "system_server";
13112        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13113            return "system_app";
13114        } else {
13115            return "data_app";
13116        }
13117    }
13118
13119    /**
13120     * Write a description of an error (crash, WTF, ANR) to the drop box.
13121     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13122     * @param process which caused the error, null means the system server
13123     * @param activity which triggered the error, null if unknown
13124     * @param parent activity related to the error, null if unknown
13125     * @param subject line related to the error, null if absent
13126     * @param report in long form describing the error, null if absent
13127     * @param logFile to include in the report, null if none
13128     * @param crashInfo giving an application stack trace, null if absent
13129     */
13130    public void addErrorToDropBox(String eventType,
13131            ProcessRecord process, String processName, ActivityRecord activity,
13132            ActivityRecord parent, String subject,
13133            final String report, final File logFile,
13134            final ApplicationErrorReport.CrashInfo crashInfo) {
13135        // NOTE -- this must never acquire the ActivityManagerService lock,
13136        // otherwise the watchdog may be prevented from resetting the system.
13137
13138        final String dropboxTag = processClass(process) + "_" + eventType;
13139        final DropBoxManager dbox = (DropBoxManager)
13140                mContext.getSystemService(Context.DROPBOX_SERVICE);
13141
13142        // Exit early if the dropbox isn't configured to accept this report type.
13143        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13144
13145        final StringBuilder sb = new StringBuilder(1024);
13146        appendDropBoxProcessHeaders(process, processName, sb);
13147        if (process != null) {
13148            sb.append("Foreground: ")
13149                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13150                    .append("\n");
13151        }
13152        if (activity != null) {
13153            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13154        }
13155        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13156            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13157        }
13158        if (parent != null && parent != activity) {
13159            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13160        }
13161        if (subject != null) {
13162            sb.append("Subject: ").append(subject).append("\n");
13163        }
13164        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13165        if (Debug.isDebuggerConnected()) {
13166            sb.append("Debugger: Connected\n");
13167        }
13168        sb.append("\n");
13169
13170        // Do the rest in a worker thread to avoid blocking the caller on I/O
13171        // (After this point, we shouldn't access AMS internal data structures.)
13172        Thread worker = new Thread("Error dump: " + dropboxTag) {
13173            @Override
13174            public void run() {
13175                if (report != null) {
13176                    sb.append(report);
13177                }
13178                if (logFile != null) {
13179                    try {
13180                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13181                                    "\n\n[[TRUNCATED]]"));
13182                    } catch (IOException e) {
13183                        Slog.e(TAG, "Error reading " + logFile, e);
13184                    }
13185                }
13186                if (crashInfo != null && crashInfo.stackTrace != null) {
13187                    sb.append(crashInfo.stackTrace);
13188                }
13189
13190                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13191                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13192                if (lines > 0) {
13193                    sb.append("\n");
13194
13195                    // Merge several logcat streams, and take the last N lines
13196                    InputStreamReader input = null;
13197                    try {
13198                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13199                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13200                                "-b", "crash",
13201                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13202
13203                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13204                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13205                        input = new InputStreamReader(logcat.getInputStream());
13206
13207                        int num;
13208                        char[] buf = new char[8192];
13209                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13210                    } catch (IOException e) {
13211                        Slog.e(TAG, "Error running logcat", e);
13212                    } finally {
13213                        if (input != null) try { input.close(); } catch (IOException e) {}
13214                    }
13215                }
13216
13217                dbox.addText(dropboxTag, sb.toString());
13218            }
13219        };
13220
13221        if (process == null) {
13222            // If process is null, we are being called from some internal code
13223            // and may be about to die -- run this synchronously.
13224            worker.run();
13225        } else {
13226            worker.start();
13227        }
13228    }
13229
13230    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13231        enforceNotIsolatedCaller("getProcessesInErrorState");
13232        // assume our apps are happy - lazy create the list
13233        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13234
13235        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13236                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13237        int userId = UserHandle.getUserId(Binder.getCallingUid());
13238
13239        synchronized (this) {
13240
13241            // iterate across all processes
13242            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13243                ProcessRecord app = mLruProcesses.get(i);
13244                if (!allUsers && app.userId != userId) {
13245                    continue;
13246                }
13247                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13248                    // This one's in trouble, so we'll generate a report for it
13249                    // crashes are higher priority (in case there's a crash *and* an anr)
13250                    ActivityManager.ProcessErrorStateInfo report = null;
13251                    if (app.crashing) {
13252                        report = app.crashingReport;
13253                    } else if (app.notResponding) {
13254                        report = app.notRespondingReport;
13255                    }
13256
13257                    if (report != null) {
13258                        if (errList == null) {
13259                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13260                        }
13261                        errList.add(report);
13262                    } else {
13263                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13264                                " crashing = " + app.crashing +
13265                                " notResponding = " + app.notResponding);
13266                    }
13267                }
13268            }
13269        }
13270
13271        return errList;
13272    }
13273
13274    static int procStateToImportance(int procState, int memAdj,
13275            ActivityManager.RunningAppProcessInfo currApp) {
13276        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13277        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13278            currApp.lru = memAdj;
13279        } else {
13280            currApp.lru = 0;
13281        }
13282        return imp;
13283    }
13284
13285    private void fillInProcMemInfo(ProcessRecord app,
13286            ActivityManager.RunningAppProcessInfo outInfo) {
13287        outInfo.pid = app.pid;
13288        outInfo.uid = app.info.uid;
13289        if (mHeavyWeightProcess == app) {
13290            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13291        }
13292        if (app.persistent) {
13293            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13294        }
13295        if (app.activities.size() > 0) {
13296            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13297        }
13298        outInfo.lastTrimLevel = app.trimMemoryLevel;
13299        int adj = app.curAdj;
13300        int procState = app.curProcState;
13301        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13302        outInfo.importanceReasonCode = app.adjTypeCode;
13303        outInfo.processState = app.curProcState;
13304    }
13305
13306    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13307        enforceNotIsolatedCaller("getRunningAppProcesses");
13308
13309        final int callingUid = Binder.getCallingUid();
13310
13311        // Lazy instantiation of list
13312        List<ActivityManager.RunningAppProcessInfo> runList = null;
13313        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13314                callingUid) == PackageManager.PERMISSION_GRANTED;
13315        final int userId = UserHandle.getUserId(callingUid);
13316        final boolean allUids = isGetTasksAllowed(
13317                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13318
13319        synchronized (this) {
13320            // Iterate across all processes
13321            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13322                ProcessRecord app = mLruProcesses.get(i);
13323                if ((!allUsers && app.userId != userId)
13324                        || (!allUids && app.uid != callingUid)) {
13325                    continue;
13326                }
13327                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13328                    // Generate process state info for running application
13329                    ActivityManager.RunningAppProcessInfo currApp =
13330                        new ActivityManager.RunningAppProcessInfo(app.processName,
13331                                app.pid, app.getPackageList());
13332                    fillInProcMemInfo(app, currApp);
13333                    if (app.adjSource instanceof ProcessRecord) {
13334                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13335                        currApp.importanceReasonImportance =
13336                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13337                                        app.adjSourceProcState);
13338                    } else if (app.adjSource instanceof ActivityRecord) {
13339                        ActivityRecord r = (ActivityRecord)app.adjSource;
13340                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13341                    }
13342                    if (app.adjTarget instanceof ComponentName) {
13343                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13344                    }
13345                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13346                    //        + " lru=" + currApp.lru);
13347                    if (runList == null) {
13348                        runList = new ArrayList<>();
13349                    }
13350                    runList.add(currApp);
13351                }
13352            }
13353        }
13354        return runList;
13355    }
13356
13357    public List<ApplicationInfo> getRunningExternalApplications() {
13358        enforceNotIsolatedCaller("getRunningExternalApplications");
13359        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13360        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13361        if (runningApps != null && runningApps.size() > 0) {
13362            Set<String> extList = new HashSet<String>();
13363            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13364                if (app.pkgList != null) {
13365                    for (String pkg : app.pkgList) {
13366                        extList.add(pkg);
13367                    }
13368                }
13369            }
13370            IPackageManager pm = AppGlobals.getPackageManager();
13371            for (String pkg : extList) {
13372                try {
13373                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13374                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13375                        retList.add(info);
13376                    }
13377                } catch (RemoteException e) {
13378                }
13379            }
13380        }
13381        return retList;
13382    }
13383
13384    @Override
13385    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13386        enforceNotIsolatedCaller("getMyMemoryState");
13387        synchronized (this) {
13388            ProcessRecord proc;
13389            synchronized (mPidsSelfLocked) {
13390                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13391            }
13392            fillInProcMemInfo(proc, outInfo);
13393        }
13394    }
13395
13396    @Override
13397    public int getMemoryTrimLevel() {
13398        enforceNotIsolatedCaller("getMyMemoryState");
13399        synchronized (this) {
13400            return mLastMemoryLevel;
13401        }
13402    }
13403
13404    @Override
13405    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13406            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13407        (new ActivityManagerShellCommand(this, false)).exec(
13408                this, in, out, err, args, resultReceiver);
13409    }
13410
13411    @Override
13412    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13413        if (checkCallingPermission(android.Manifest.permission.DUMP)
13414                != PackageManager.PERMISSION_GRANTED) {
13415            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13416                    + Binder.getCallingPid()
13417                    + ", uid=" + Binder.getCallingUid()
13418                    + " without permission "
13419                    + android.Manifest.permission.DUMP);
13420            return;
13421        }
13422
13423        boolean dumpAll = false;
13424        boolean dumpClient = false;
13425        String dumpPackage = null;
13426
13427        int opti = 0;
13428        while (opti < args.length) {
13429            String opt = args[opti];
13430            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13431                break;
13432            }
13433            opti++;
13434            if ("-a".equals(opt)) {
13435                dumpAll = true;
13436            } else if ("-c".equals(opt)) {
13437                dumpClient = true;
13438            } else if ("-p".equals(opt)) {
13439                if (opti < args.length) {
13440                    dumpPackage = args[opti];
13441                    opti++;
13442                } else {
13443                    pw.println("Error: -p option requires package argument");
13444                    return;
13445                }
13446                dumpClient = true;
13447            } else if ("-h".equals(opt)) {
13448                ActivityManagerShellCommand.dumpHelp(pw, true);
13449                return;
13450            } else {
13451                pw.println("Unknown argument: " + opt + "; use -h for help");
13452            }
13453        }
13454
13455        long origId = Binder.clearCallingIdentity();
13456        boolean more = false;
13457        // Is the caller requesting to dump a particular piece of data?
13458        if (opti < args.length) {
13459            String cmd = args[opti];
13460            opti++;
13461            if ("activities".equals(cmd) || "a".equals(cmd)) {
13462                synchronized (this) {
13463                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13464                }
13465            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13466                synchronized (this) {
13467                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13468                }
13469            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13470                String[] newArgs;
13471                String name;
13472                if (opti >= args.length) {
13473                    name = null;
13474                    newArgs = EMPTY_STRING_ARRAY;
13475                } else {
13476                    dumpPackage = args[opti];
13477                    opti++;
13478                    newArgs = new String[args.length - opti];
13479                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13480                            args.length - opti);
13481                }
13482                synchronized (this) {
13483                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13484                }
13485            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13486                String[] newArgs;
13487                String name;
13488                if (opti >= args.length) {
13489                    name = null;
13490                    newArgs = EMPTY_STRING_ARRAY;
13491                } else {
13492                    dumpPackage = args[opti];
13493                    opti++;
13494                    newArgs = new String[args.length - opti];
13495                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13496                            args.length - opti);
13497                }
13498                synchronized (this) {
13499                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13500                }
13501            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13502                String[] newArgs;
13503                String name;
13504                if (opti >= args.length) {
13505                    name = null;
13506                    newArgs = EMPTY_STRING_ARRAY;
13507                } else {
13508                    dumpPackage = args[opti];
13509                    opti++;
13510                    newArgs = new String[args.length - opti];
13511                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13512                            args.length - opti);
13513                }
13514                synchronized (this) {
13515                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13516                }
13517            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13518                synchronized (this) {
13519                    dumpOomLocked(fd, pw, args, opti, true);
13520                }
13521            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13522                synchronized (this) {
13523                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13524                }
13525            } else if ("provider".equals(cmd)) {
13526                String[] newArgs;
13527                String name;
13528                if (opti >= args.length) {
13529                    name = null;
13530                    newArgs = EMPTY_STRING_ARRAY;
13531                } else {
13532                    name = args[opti];
13533                    opti++;
13534                    newArgs = new String[args.length - opti];
13535                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13536                }
13537                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13538                    pw.println("No providers match: " + name);
13539                    pw.println("Use -h for help.");
13540                }
13541            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13542                synchronized (this) {
13543                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13544                }
13545            } else if ("service".equals(cmd)) {
13546                String[] newArgs;
13547                String name;
13548                if (opti >= args.length) {
13549                    name = null;
13550                    newArgs = EMPTY_STRING_ARRAY;
13551                } else {
13552                    name = args[opti];
13553                    opti++;
13554                    newArgs = new String[args.length - opti];
13555                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13556                            args.length - opti);
13557                }
13558                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13559                    pw.println("No services match: " + name);
13560                    pw.println("Use -h for help.");
13561                }
13562            } else if ("package".equals(cmd)) {
13563                String[] newArgs;
13564                if (opti >= args.length) {
13565                    pw.println("package: no package name specified");
13566                    pw.println("Use -h for help.");
13567                } else {
13568                    dumpPackage = args[opti];
13569                    opti++;
13570                    newArgs = new String[args.length - opti];
13571                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13572                            args.length - opti);
13573                    args = newArgs;
13574                    opti = 0;
13575                    more = true;
13576                }
13577            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13578                synchronized (this) {
13579                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13580                }
13581            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13582                synchronized (this) {
13583                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13584                }
13585            } else {
13586                // Dumping a single activity?
13587                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13588                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13589                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13590                    if (res < 0) {
13591                        pw.println("Bad activity command, or no activities match: " + cmd);
13592                        pw.println("Use -h for help.");
13593                    }
13594                }
13595            }
13596            if (!more) {
13597                Binder.restoreCallingIdentity(origId);
13598                return;
13599            }
13600        }
13601
13602        // No piece of data specified, dump everything.
13603        synchronized (this) {
13604            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13605            pw.println();
13606            if (dumpAll) {
13607                pw.println("-------------------------------------------------------------------------------");
13608            }
13609            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13610            pw.println();
13611            if (dumpAll) {
13612                pw.println("-------------------------------------------------------------------------------");
13613            }
13614            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13615            pw.println();
13616            if (dumpAll) {
13617                pw.println("-------------------------------------------------------------------------------");
13618            }
13619            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13620            pw.println();
13621            if (dumpAll) {
13622                pw.println("-------------------------------------------------------------------------------");
13623            }
13624            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13625            pw.println();
13626            if (dumpAll) {
13627                pw.println("-------------------------------------------------------------------------------");
13628            }
13629            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13630            pw.println();
13631            if (dumpAll) {
13632                pw.println("-------------------------------------------------------------------------------");
13633            }
13634            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13635            if (mAssociations.size() > 0) {
13636                pw.println();
13637                if (dumpAll) {
13638                    pw.println("-------------------------------------------------------------------------------");
13639                }
13640                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13641            }
13642            pw.println();
13643            if (dumpAll) {
13644                pw.println("-------------------------------------------------------------------------------");
13645            }
13646            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13647        }
13648        Binder.restoreCallingIdentity(origId);
13649    }
13650
13651    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13652            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13653        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13654
13655        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13656                dumpPackage);
13657        boolean needSep = printedAnything;
13658
13659        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13660                dumpPackage, needSep, "  mFocusedActivity: ");
13661        if (printed) {
13662            printedAnything = true;
13663            needSep = false;
13664        }
13665
13666        if (dumpPackage == null) {
13667            if (needSep) {
13668                pw.println();
13669            }
13670            needSep = true;
13671            printedAnything = true;
13672            mStackSupervisor.dump(pw, "  ");
13673        }
13674
13675        if (!printedAnything) {
13676            pw.println("  (nothing)");
13677        }
13678    }
13679
13680    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13681            int opti, boolean dumpAll, String dumpPackage) {
13682        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13683
13684        boolean printedAnything = false;
13685
13686        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13687            boolean printedHeader = false;
13688
13689            final int N = mRecentTasks.size();
13690            for (int i=0; i<N; i++) {
13691                TaskRecord tr = mRecentTasks.get(i);
13692                if (dumpPackage != null) {
13693                    if (tr.realActivity == null ||
13694                            !dumpPackage.equals(tr.realActivity)) {
13695                        continue;
13696                    }
13697                }
13698                if (!printedHeader) {
13699                    pw.println("  Recent tasks:");
13700                    printedHeader = true;
13701                    printedAnything = true;
13702                }
13703                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13704                        pw.println(tr);
13705                if (dumpAll) {
13706                    mRecentTasks.get(i).dump(pw, "    ");
13707                }
13708            }
13709        }
13710
13711        if (!printedAnything) {
13712            pw.println("  (nothing)");
13713        }
13714    }
13715
13716    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13717            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13718        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13719
13720        int dumpUid = 0;
13721        if (dumpPackage != null) {
13722            IPackageManager pm = AppGlobals.getPackageManager();
13723            try {
13724                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13725            } catch (RemoteException e) {
13726            }
13727        }
13728
13729        boolean printedAnything = false;
13730
13731        final long now = SystemClock.uptimeMillis();
13732
13733        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13734            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13735                    = mAssociations.valueAt(i1);
13736            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13737                SparseArray<ArrayMap<String, Association>> sourceUids
13738                        = targetComponents.valueAt(i2);
13739                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13740                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13741                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13742                        Association ass = sourceProcesses.valueAt(i4);
13743                        if (dumpPackage != null) {
13744                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13745                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13746                                continue;
13747                            }
13748                        }
13749                        printedAnything = true;
13750                        pw.print("  ");
13751                        pw.print(ass.mTargetProcess);
13752                        pw.print("/");
13753                        UserHandle.formatUid(pw, ass.mTargetUid);
13754                        pw.print(" <- ");
13755                        pw.print(ass.mSourceProcess);
13756                        pw.print("/");
13757                        UserHandle.formatUid(pw, ass.mSourceUid);
13758                        pw.println();
13759                        pw.print("    via ");
13760                        pw.print(ass.mTargetComponent.flattenToShortString());
13761                        pw.println();
13762                        pw.print("    ");
13763                        long dur = ass.mTime;
13764                        if (ass.mNesting > 0) {
13765                            dur += now - ass.mStartTime;
13766                        }
13767                        TimeUtils.formatDuration(dur, pw);
13768                        pw.print(" (");
13769                        pw.print(ass.mCount);
13770                        pw.println(" times)");
13771                        if (ass.mNesting > 0) {
13772                            pw.print("    ");
13773                            pw.print(" Currently active: ");
13774                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13775                            pw.println();
13776                        }
13777                    }
13778                }
13779            }
13780
13781        }
13782
13783        if (!printedAnything) {
13784            pw.println("  (nothing)");
13785        }
13786    }
13787
13788    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13789            String header, boolean needSep) {
13790        boolean printed = false;
13791        int whichAppId = -1;
13792        if (dumpPackage != null) {
13793            try {
13794                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13795                        dumpPackage, 0);
13796                whichAppId = UserHandle.getAppId(info.uid);
13797            } catch (NameNotFoundException e) {
13798                e.printStackTrace();
13799            }
13800        }
13801        for (int i=0; i<uids.size(); i++) {
13802            UidRecord uidRec = uids.valueAt(i);
13803            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13804                continue;
13805            }
13806            if (!printed) {
13807                printed = true;
13808                if (needSep) {
13809                    pw.println();
13810                }
13811                pw.print("  ");
13812                pw.println(header);
13813                needSep = true;
13814            }
13815            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13816            pw.print(": "); pw.println(uidRec);
13817        }
13818        return printed;
13819    }
13820
13821    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13822            int opti, boolean dumpAll, String dumpPackage) {
13823        boolean needSep = false;
13824        boolean printedAnything = false;
13825        int numPers = 0;
13826
13827        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13828
13829        if (dumpAll) {
13830            final int NP = mProcessNames.getMap().size();
13831            for (int ip=0; ip<NP; ip++) {
13832                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13833                final int NA = procs.size();
13834                for (int ia=0; ia<NA; ia++) {
13835                    ProcessRecord r = procs.valueAt(ia);
13836                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13837                        continue;
13838                    }
13839                    if (!needSep) {
13840                        pw.println("  All known processes:");
13841                        needSep = true;
13842                        printedAnything = true;
13843                    }
13844                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13845                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13846                        pw.print(" "); pw.println(r);
13847                    r.dump(pw, "    ");
13848                    if (r.persistent) {
13849                        numPers++;
13850                    }
13851                }
13852            }
13853        }
13854
13855        if (mIsolatedProcesses.size() > 0) {
13856            boolean printed = false;
13857            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13858                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13859                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13860                    continue;
13861                }
13862                if (!printed) {
13863                    if (needSep) {
13864                        pw.println();
13865                    }
13866                    pw.println("  Isolated process list (sorted by uid):");
13867                    printedAnything = true;
13868                    printed = true;
13869                    needSep = true;
13870                }
13871                pw.println(String.format("%sIsolated #%2d: %s",
13872                        "    ", i, r.toString()));
13873            }
13874        }
13875
13876        if (mActiveUids.size() > 0) {
13877            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13878                printedAnything = needSep = true;
13879            }
13880        }
13881        if (mValidateUids.size() > 0) {
13882            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13883                printedAnything = needSep = true;
13884            }
13885        }
13886
13887        if (mLruProcesses.size() > 0) {
13888            if (needSep) {
13889                pw.println();
13890            }
13891            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13892                    pw.print(" total, non-act at ");
13893                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13894                    pw.print(", non-svc at ");
13895                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13896                    pw.println("):");
13897            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13898            needSep = true;
13899            printedAnything = true;
13900        }
13901
13902        if (dumpAll || dumpPackage != null) {
13903            synchronized (mPidsSelfLocked) {
13904                boolean printed = false;
13905                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13906                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13907                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13908                        continue;
13909                    }
13910                    if (!printed) {
13911                        if (needSep) pw.println();
13912                        needSep = true;
13913                        pw.println("  PID mappings:");
13914                        printed = true;
13915                        printedAnything = true;
13916                    }
13917                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13918                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13919                }
13920            }
13921        }
13922
13923        if (mForegroundProcesses.size() > 0) {
13924            synchronized (mPidsSelfLocked) {
13925                boolean printed = false;
13926                for (int i=0; i<mForegroundProcesses.size(); i++) {
13927                    ProcessRecord r = mPidsSelfLocked.get(
13928                            mForegroundProcesses.valueAt(i).pid);
13929                    if (dumpPackage != null && (r == null
13930                            || !r.pkgList.containsKey(dumpPackage))) {
13931                        continue;
13932                    }
13933                    if (!printed) {
13934                        if (needSep) pw.println();
13935                        needSep = true;
13936                        pw.println("  Foreground Processes:");
13937                        printed = true;
13938                        printedAnything = true;
13939                    }
13940                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13941                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13942                }
13943            }
13944        }
13945
13946        if (mPersistentStartingProcesses.size() > 0) {
13947            if (needSep) pw.println();
13948            needSep = true;
13949            printedAnything = true;
13950            pw.println("  Persisent processes that are starting:");
13951            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13952                    "Starting Norm", "Restarting PERS", dumpPackage);
13953        }
13954
13955        if (mRemovedProcesses.size() > 0) {
13956            if (needSep) pw.println();
13957            needSep = true;
13958            printedAnything = true;
13959            pw.println("  Processes that are being removed:");
13960            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13961                    "Removed Norm", "Removed PERS", dumpPackage);
13962        }
13963
13964        if (mProcessesOnHold.size() > 0) {
13965            if (needSep) pw.println();
13966            needSep = true;
13967            printedAnything = true;
13968            pw.println("  Processes that are on old until the system is ready:");
13969            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13970                    "OnHold Norm", "OnHold PERS", dumpPackage);
13971        }
13972
13973        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13974
13975        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
13976        if (needSep) {
13977            printedAnything = true;
13978        }
13979
13980        if (dumpPackage == null) {
13981            pw.println();
13982            needSep = false;
13983            mUserController.dump(pw, dumpAll);
13984        }
13985        if (mHomeProcess != null && (dumpPackage == null
13986                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13987            if (needSep) {
13988                pw.println();
13989                needSep = false;
13990            }
13991            pw.println("  mHomeProcess: " + mHomeProcess);
13992        }
13993        if (mPreviousProcess != null && (dumpPackage == null
13994                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13995            if (needSep) {
13996                pw.println();
13997                needSep = false;
13998            }
13999            pw.println("  mPreviousProcess: " + mPreviousProcess);
14000        }
14001        if (dumpAll) {
14002            StringBuilder sb = new StringBuilder(128);
14003            sb.append("  mPreviousProcessVisibleTime: ");
14004            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14005            pw.println(sb);
14006        }
14007        if (mHeavyWeightProcess != null && (dumpPackage == null
14008                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14009            if (needSep) {
14010                pw.println();
14011                needSep = false;
14012            }
14013            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14014        }
14015        if (dumpPackage == null) {
14016            pw.println("  mConfiguration: " + mConfiguration);
14017        }
14018        if (dumpAll) {
14019            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14020            if (mCompatModePackages.getPackages().size() > 0) {
14021                boolean printed = false;
14022                for (Map.Entry<String, Integer> entry
14023                        : mCompatModePackages.getPackages().entrySet()) {
14024                    String pkg = entry.getKey();
14025                    int mode = entry.getValue();
14026                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14027                        continue;
14028                    }
14029                    if (!printed) {
14030                        pw.println("  mScreenCompatPackages:");
14031                        printed = true;
14032                    }
14033                    pw.print("    "); pw.print(pkg); pw.print(": ");
14034                            pw.print(mode); pw.println();
14035                }
14036            }
14037        }
14038        if (dumpPackage == null) {
14039            pw.println("  mWakefulness="
14040                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14041            pw.println("  mSleepTokens=" + mSleepTokens);
14042            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14043                    + lockScreenShownToString());
14044            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14045            if (mRunningVoice != null) {
14046                pw.println("  mRunningVoice=" + mRunningVoice);
14047                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14048            }
14049        }
14050        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14051                || mOrigWaitForDebugger) {
14052            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14053                    || dumpPackage.equals(mOrigDebugApp)) {
14054                if (needSep) {
14055                    pw.println();
14056                    needSep = false;
14057                }
14058                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14059                        + " mDebugTransient=" + mDebugTransient
14060                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14061            }
14062        }
14063        if (mCurAppTimeTracker != null) {
14064            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14065        }
14066        if (mMemWatchProcesses.getMap().size() > 0) {
14067            pw.println("  Mem watch processes:");
14068            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14069                    = mMemWatchProcesses.getMap();
14070            for (int i=0; i<procs.size(); i++) {
14071                final String proc = procs.keyAt(i);
14072                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14073                for (int j=0; j<uids.size(); j++) {
14074                    if (needSep) {
14075                        pw.println();
14076                        needSep = false;
14077                    }
14078                    StringBuilder sb = new StringBuilder();
14079                    sb.append("    ").append(proc).append('/');
14080                    UserHandle.formatUid(sb, uids.keyAt(j));
14081                    Pair<Long, String> val = uids.valueAt(j);
14082                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14083                    if (val.second != null) {
14084                        sb.append(", report to ").append(val.second);
14085                    }
14086                    pw.println(sb.toString());
14087                }
14088            }
14089            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14090            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14091            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14092                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14093        }
14094        if (mTrackAllocationApp != null) {
14095            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14096                if (needSep) {
14097                    pw.println();
14098                    needSep = false;
14099                }
14100                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14101            }
14102        }
14103        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14104                || mProfileFd != null) {
14105            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14106                if (needSep) {
14107                    pw.println();
14108                    needSep = false;
14109                }
14110                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14111                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14112                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14113                        + mAutoStopProfiler);
14114                pw.println("  mProfileType=" + mProfileType);
14115            }
14116        }
14117        if (mNativeDebuggingApp != null) {
14118            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14119                if (needSep) {
14120                    pw.println();
14121                    needSep = false;
14122                }
14123                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14124            }
14125        }
14126        if (dumpPackage == null) {
14127            if (mAlwaysFinishActivities || mLenientBackgroundCheck || mController != null) {
14128                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14129                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck
14130                        + " mController=" + mController);
14131            }
14132            if (dumpAll) {
14133                pw.println("  Total persistent processes: " + numPers);
14134                pw.println("  mProcessesReady=" + mProcessesReady
14135                        + " mSystemReady=" + mSystemReady
14136                        + " mBooted=" + mBooted
14137                        + " mFactoryTest=" + mFactoryTest);
14138                pw.println("  mBooting=" + mBooting
14139                        + " mCallFinishBooting=" + mCallFinishBooting
14140                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14141                pw.print("  mLastPowerCheckRealtime=");
14142                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14143                        pw.println("");
14144                pw.print("  mLastPowerCheckUptime=");
14145                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14146                        pw.println("");
14147                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14148                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14149                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14150                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14151                        + " (" + mLruProcesses.size() + " total)"
14152                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14153                        + " mNumServiceProcs=" + mNumServiceProcs
14154                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14155                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14156                        + " mLastMemoryLevel" + mLastMemoryLevel
14157                        + " mLastNumProcesses" + mLastNumProcesses);
14158                long now = SystemClock.uptimeMillis();
14159                pw.print("  mLastIdleTime=");
14160                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14161                        pw.print(" mLowRamSinceLastIdle=");
14162                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14163                        pw.println();
14164            }
14165        }
14166
14167        if (!printedAnything) {
14168            pw.println("  (nothing)");
14169        }
14170    }
14171
14172    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14173            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14174        if (mProcessesToGc.size() > 0) {
14175            boolean printed = false;
14176            long now = SystemClock.uptimeMillis();
14177            for (int i=0; i<mProcessesToGc.size(); i++) {
14178                ProcessRecord proc = mProcessesToGc.get(i);
14179                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14180                    continue;
14181                }
14182                if (!printed) {
14183                    if (needSep) pw.println();
14184                    needSep = true;
14185                    pw.println("  Processes that are waiting to GC:");
14186                    printed = true;
14187                }
14188                pw.print("    Process "); pw.println(proc);
14189                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14190                        pw.print(", last gced=");
14191                        pw.print(now-proc.lastRequestedGc);
14192                        pw.print(" ms ago, last lowMem=");
14193                        pw.print(now-proc.lastLowMemory);
14194                        pw.println(" ms ago");
14195
14196            }
14197        }
14198        return needSep;
14199    }
14200
14201    void printOomLevel(PrintWriter pw, String name, int adj) {
14202        pw.print("    ");
14203        if (adj >= 0) {
14204            pw.print(' ');
14205            if (adj < 10) pw.print(' ');
14206        } else {
14207            if (adj > -10) pw.print(' ');
14208        }
14209        pw.print(adj);
14210        pw.print(": ");
14211        pw.print(name);
14212        pw.print(" (");
14213        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14214        pw.println(")");
14215    }
14216
14217    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14218            int opti, boolean dumpAll) {
14219        boolean needSep = false;
14220
14221        if (mLruProcesses.size() > 0) {
14222            if (needSep) pw.println();
14223            needSep = true;
14224            pw.println("  OOM levels:");
14225            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14226            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14227            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14228            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14229            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14230            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14231            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14232            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14233            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14234            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14235            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14236            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14237            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14238            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14239
14240            if (needSep) pw.println();
14241            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14242                    pw.print(" total, non-act at ");
14243                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14244                    pw.print(", non-svc at ");
14245                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14246                    pw.println("):");
14247            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14248            needSep = true;
14249        }
14250
14251        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14252
14253        pw.println();
14254        pw.println("  mHomeProcess: " + mHomeProcess);
14255        pw.println("  mPreviousProcess: " + mPreviousProcess);
14256        if (mHeavyWeightProcess != null) {
14257            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14258        }
14259
14260        return true;
14261    }
14262
14263    /**
14264     * There are three ways to call this:
14265     *  - no provider specified: dump all the providers
14266     *  - a flattened component name that matched an existing provider was specified as the
14267     *    first arg: dump that one provider
14268     *  - the first arg isn't the flattened component name of an existing provider:
14269     *    dump all providers whose component contains the first arg as a substring
14270     */
14271    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14272            int opti, boolean dumpAll) {
14273        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14274    }
14275
14276    static class ItemMatcher {
14277        ArrayList<ComponentName> components;
14278        ArrayList<String> strings;
14279        ArrayList<Integer> objects;
14280        boolean all;
14281
14282        ItemMatcher() {
14283            all = true;
14284        }
14285
14286        void build(String name) {
14287            ComponentName componentName = ComponentName.unflattenFromString(name);
14288            if (componentName != null) {
14289                if (components == null) {
14290                    components = new ArrayList<ComponentName>();
14291                }
14292                components.add(componentName);
14293                all = false;
14294            } else {
14295                int objectId = 0;
14296                // Not a '/' separated full component name; maybe an object ID?
14297                try {
14298                    objectId = Integer.parseInt(name, 16);
14299                    if (objects == null) {
14300                        objects = new ArrayList<Integer>();
14301                    }
14302                    objects.add(objectId);
14303                    all = false;
14304                } catch (RuntimeException e) {
14305                    // Not an integer; just do string match.
14306                    if (strings == null) {
14307                        strings = new ArrayList<String>();
14308                    }
14309                    strings.add(name);
14310                    all = false;
14311                }
14312            }
14313        }
14314
14315        int build(String[] args, int opti) {
14316            for (; opti<args.length; opti++) {
14317                String name = args[opti];
14318                if ("--".equals(name)) {
14319                    return opti+1;
14320                }
14321                build(name);
14322            }
14323            return opti;
14324        }
14325
14326        boolean match(Object object, ComponentName comp) {
14327            if (all) {
14328                return true;
14329            }
14330            if (components != null) {
14331                for (int i=0; i<components.size(); i++) {
14332                    if (components.get(i).equals(comp)) {
14333                        return true;
14334                    }
14335                }
14336            }
14337            if (objects != null) {
14338                for (int i=0; i<objects.size(); i++) {
14339                    if (System.identityHashCode(object) == objects.get(i)) {
14340                        return true;
14341                    }
14342                }
14343            }
14344            if (strings != null) {
14345                String flat = comp.flattenToString();
14346                for (int i=0; i<strings.size(); i++) {
14347                    if (flat.contains(strings.get(i))) {
14348                        return true;
14349                    }
14350                }
14351            }
14352            return false;
14353        }
14354    }
14355
14356    /**
14357     * There are three things that cmd can be:
14358     *  - a flattened component name that matches an existing activity
14359     *  - the cmd arg isn't the flattened component name of an existing activity:
14360     *    dump all activity whose component contains the cmd as a substring
14361     *  - A hex number of the ActivityRecord object instance.
14362     */
14363    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14364            int opti, boolean dumpAll) {
14365        ArrayList<ActivityRecord> activities;
14366
14367        synchronized (this) {
14368            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14369        }
14370
14371        if (activities.size() <= 0) {
14372            return false;
14373        }
14374
14375        String[] newArgs = new String[args.length - opti];
14376        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14377
14378        TaskRecord lastTask = null;
14379        boolean needSep = false;
14380        for (int i=activities.size()-1; i>=0; i--) {
14381            ActivityRecord r = activities.get(i);
14382            if (needSep) {
14383                pw.println();
14384            }
14385            needSep = true;
14386            synchronized (this) {
14387                if (lastTask != r.task) {
14388                    lastTask = r.task;
14389                    pw.print("TASK "); pw.print(lastTask.affinity);
14390                            pw.print(" id="); pw.println(lastTask.taskId);
14391                    if (dumpAll) {
14392                        lastTask.dump(pw, "  ");
14393                    }
14394                }
14395            }
14396            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14397        }
14398        return true;
14399    }
14400
14401    /**
14402     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14403     * there is a thread associated with the activity.
14404     */
14405    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14406            final ActivityRecord r, String[] args, boolean dumpAll) {
14407        String innerPrefix = prefix + "  ";
14408        synchronized (this) {
14409            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14410                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14411                    pw.print(" pid=");
14412                    if (r.app != null) pw.println(r.app.pid);
14413                    else pw.println("(not running)");
14414            if (dumpAll) {
14415                r.dump(pw, innerPrefix);
14416            }
14417        }
14418        if (r.app != null && r.app.thread != null) {
14419            // flush anything that is already in the PrintWriter since the thread is going
14420            // to write to the file descriptor directly
14421            pw.flush();
14422            try {
14423                TransferPipe tp = new TransferPipe();
14424                try {
14425                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14426                            r.appToken, innerPrefix, args);
14427                    tp.go(fd);
14428                } finally {
14429                    tp.kill();
14430                }
14431            } catch (IOException e) {
14432                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14433            } catch (RemoteException e) {
14434                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14435            }
14436        }
14437    }
14438
14439    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14440            int opti, boolean dumpAll, String dumpPackage) {
14441        boolean needSep = false;
14442        boolean onlyHistory = false;
14443        boolean printedAnything = false;
14444
14445        if ("history".equals(dumpPackage)) {
14446            if (opti < args.length && "-s".equals(args[opti])) {
14447                dumpAll = false;
14448            }
14449            onlyHistory = true;
14450            dumpPackage = null;
14451        }
14452
14453        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14454        if (!onlyHistory && dumpAll) {
14455            if (mRegisteredReceivers.size() > 0) {
14456                boolean printed = false;
14457                Iterator it = mRegisteredReceivers.values().iterator();
14458                while (it.hasNext()) {
14459                    ReceiverList r = (ReceiverList)it.next();
14460                    if (dumpPackage != null && (r.app == null ||
14461                            !dumpPackage.equals(r.app.info.packageName))) {
14462                        continue;
14463                    }
14464                    if (!printed) {
14465                        pw.println("  Registered Receivers:");
14466                        needSep = true;
14467                        printed = true;
14468                        printedAnything = true;
14469                    }
14470                    pw.print("  * "); pw.println(r);
14471                    r.dump(pw, "    ");
14472                }
14473            }
14474
14475            if (mReceiverResolver.dump(pw, needSep ?
14476                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14477                    "    ", dumpPackage, false, false)) {
14478                needSep = true;
14479                printedAnything = true;
14480            }
14481        }
14482
14483        for (BroadcastQueue q : mBroadcastQueues) {
14484            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14485            printedAnything |= needSep;
14486        }
14487
14488        needSep = true;
14489
14490        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14491            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14492                if (needSep) {
14493                    pw.println();
14494                }
14495                needSep = true;
14496                printedAnything = true;
14497                pw.print("  Sticky broadcasts for user ");
14498                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14499                StringBuilder sb = new StringBuilder(128);
14500                for (Map.Entry<String, ArrayList<Intent>> ent
14501                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14502                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14503                    if (dumpAll) {
14504                        pw.println(":");
14505                        ArrayList<Intent> intents = ent.getValue();
14506                        final int N = intents.size();
14507                        for (int i=0; i<N; i++) {
14508                            sb.setLength(0);
14509                            sb.append("    Intent: ");
14510                            intents.get(i).toShortString(sb, false, true, false, false);
14511                            pw.println(sb.toString());
14512                            Bundle bundle = intents.get(i).getExtras();
14513                            if (bundle != null) {
14514                                pw.print("      ");
14515                                pw.println(bundle.toString());
14516                            }
14517                        }
14518                    } else {
14519                        pw.println("");
14520                    }
14521                }
14522            }
14523        }
14524
14525        if (!onlyHistory && dumpAll) {
14526            pw.println();
14527            for (BroadcastQueue queue : mBroadcastQueues) {
14528                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14529                        + queue.mBroadcastsScheduled);
14530            }
14531            pw.println("  mHandler:");
14532            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14533            needSep = true;
14534            printedAnything = true;
14535        }
14536
14537        if (!printedAnything) {
14538            pw.println("  (nothing)");
14539        }
14540    }
14541
14542    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14543            int opti, boolean dumpAll, String dumpPackage) {
14544        boolean needSep;
14545        boolean printedAnything = false;
14546
14547        ItemMatcher matcher = new ItemMatcher();
14548        matcher.build(args, opti);
14549
14550        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14551
14552        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14553        printedAnything |= needSep;
14554
14555        if (mLaunchingProviders.size() > 0) {
14556            boolean printed = false;
14557            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14558                ContentProviderRecord r = mLaunchingProviders.get(i);
14559                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14560                    continue;
14561                }
14562                if (!printed) {
14563                    if (needSep) pw.println();
14564                    needSep = true;
14565                    pw.println("  Launching content providers:");
14566                    printed = true;
14567                    printedAnything = true;
14568                }
14569                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14570                        pw.println(r);
14571            }
14572        }
14573
14574        if (!printedAnything) {
14575            pw.println("  (nothing)");
14576        }
14577    }
14578
14579    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14580            int opti, boolean dumpAll, String dumpPackage) {
14581        boolean needSep = false;
14582        boolean printedAnything = false;
14583
14584        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14585
14586        if (mGrantedUriPermissions.size() > 0) {
14587            boolean printed = false;
14588            int dumpUid = -2;
14589            if (dumpPackage != null) {
14590                try {
14591                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14592                            MATCH_UNINSTALLED_PACKAGES, 0);
14593                } catch (NameNotFoundException e) {
14594                    dumpUid = -1;
14595                }
14596            }
14597            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14598                int uid = mGrantedUriPermissions.keyAt(i);
14599                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14600                    continue;
14601                }
14602                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14603                if (!printed) {
14604                    if (needSep) pw.println();
14605                    needSep = true;
14606                    pw.println("  Granted Uri Permissions:");
14607                    printed = true;
14608                    printedAnything = true;
14609                }
14610                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14611                for (UriPermission perm : perms.values()) {
14612                    pw.print("    "); pw.println(perm);
14613                    if (dumpAll) {
14614                        perm.dump(pw, "      ");
14615                    }
14616                }
14617            }
14618        }
14619
14620        if (!printedAnything) {
14621            pw.println("  (nothing)");
14622        }
14623    }
14624
14625    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14626            int opti, boolean dumpAll, String dumpPackage) {
14627        boolean printed = false;
14628
14629        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14630
14631        if (mIntentSenderRecords.size() > 0) {
14632            Iterator<WeakReference<PendingIntentRecord>> it
14633                    = mIntentSenderRecords.values().iterator();
14634            while (it.hasNext()) {
14635                WeakReference<PendingIntentRecord> ref = it.next();
14636                PendingIntentRecord rec = ref != null ? ref.get(): null;
14637                if (dumpPackage != null && (rec == null
14638                        || !dumpPackage.equals(rec.key.packageName))) {
14639                    continue;
14640                }
14641                printed = true;
14642                if (rec != null) {
14643                    pw.print("  * "); pw.println(rec);
14644                    if (dumpAll) {
14645                        rec.dump(pw, "    ");
14646                    }
14647                } else {
14648                    pw.print("  * "); pw.println(ref);
14649                }
14650            }
14651        }
14652
14653        if (!printed) {
14654            pw.println("  (nothing)");
14655        }
14656    }
14657
14658    private static final int dumpProcessList(PrintWriter pw,
14659            ActivityManagerService service, List list,
14660            String prefix, String normalLabel, String persistentLabel,
14661            String dumpPackage) {
14662        int numPers = 0;
14663        final int N = list.size()-1;
14664        for (int i=N; i>=0; i--) {
14665            ProcessRecord r = (ProcessRecord)list.get(i);
14666            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14667                continue;
14668            }
14669            pw.println(String.format("%s%s #%2d: %s",
14670                    prefix, (r.persistent ? persistentLabel : normalLabel),
14671                    i, r.toString()));
14672            if (r.persistent) {
14673                numPers++;
14674            }
14675        }
14676        return numPers;
14677    }
14678
14679    private static final boolean dumpProcessOomList(PrintWriter pw,
14680            ActivityManagerService service, List<ProcessRecord> origList,
14681            String prefix, String normalLabel, String persistentLabel,
14682            boolean inclDetails, String dumpPackage) {
14683
14684        ArrayList<Pair<ProcessRecord, Integer>> list
14685                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14686        for (int i=0; i<origList.size(); i++) {
14687            ProcessRecord r = origList.get(i);
14688            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14689                continue;
14690            }
14691            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14692        }
14693
14694        if (list.size() <= 0) {
14695            return false;
14696        }
14697
14698        Comparator<Pair<ProcessRecord, Integer>> comparator
14699                = new Comparator<Pair<ProcessRecord, Integer>>() {
14700            @Override
14701            public int compare(Pair<ProcessRecord, Integer> object1,
14702                    Pair<ProcessRecord, Integer> object2) {
14703                if (object1.first.setAdj != object2.first.setAdj) {
14704                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14705                }
14706                if (object1.first.setProcState != object2.first.setProcState) {
14707                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14708                }
14709                if (object1.second.intValue() != object2.second.intValue()) {
14710                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14711                }
14712                return 0;
14713            }
14714        };
14715
14716        Collections.sort(list, comparator);
14717
14718        final long curRealtime = SystemClock.elapsedRealtime();
14719        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14720        final long curUptime = SystemClock.uptimeMillis();
14721        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14722
14723        for (int i=list.size()-1; i>=0; i--) {
14724            ProcessRecord r = list.get(i).first;
14725            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14726            char schedGroup;
14727            switch (r.setSchedGroup) {
14728                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14729                    schedGroup = 'B';
14730                    break;
14731                case Process.THREAD_GROUP_DEFAULT:
14732                    schedGroup = 'F';
14733                    break;
14734                case Process.THREAD_GROUP_TOP_APP:
14735                    schedGroup = 'T';
14736                    break;
14737                default:
14738                    schedGroup = '?';
14739                    break;
14740            }
14741            char foreground;
14742            if (r.foregroundActivities) {
14743                foreground = 'A';
14744            } else if (r.foregroundServices) {
14745                foreground = 'S';
14746            } else {
14747                foreground = ' ';
14748            }
14749            String procState = ProcessList.makeProcStateString(r.curProcState);
14750            pw.print(prefix);
14751            pw.print(r.persistent ? persistentLabel : normalLabel);
14752            pw.print(" #");
14753            int num = (origList.size()-1)-list.get(i).second;
14754            if (num < 10) pw.print(' ');
14755            pw.print(num);
14756            pw.print(": ");
14757            pw.print(oomAdj);
14758            pw.print(' ');
14759            pw.print(schedGroup);
14760            pw.print('/');
14761            pw.print(foreground);
14762            pw.print('/');
14763            pw.print(procState);
14764            pw.print(" trm:");
14765            if (r.trimMemoryLevel < 10) pw.print(' ');
14766            pw.print(r.trimMemoryLevel);
14767            pw.print(' ');
14768            pw.print(r.toShortString());
14769            pw.print(" (");
14770            pw.print(r.adjType);
14771            pw.println(')');
14772            if (r.adjSource != null || r.adjTarget != null) {
14773                pw.print(prefix);
14774                pw.print("    ");
14775                if (r.adjTarget instanceof ComponentName) {
14776                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14777                } else if (r.adjTarget != null) {
14778                    pw.print(r.adjTarget.toString());
14779                } else {
14780                    pw.print("{null}");
14781                }
14782                pw.print("<=");
14783                if (r.adjSource instanceof ProcessRecord) {
14784                    pw.print("Proc{");
14785                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14786                    pw.println("}");
14787                } else if (r.adjSource != null) {
14788                    pw.println(r.adjSource.toString());
14789                } else {
14790                    pw.println("{null}");
14791                }
14792            }
14793            if (inclDetails) {
14794                pw.print(prefix);
14795                pw.print("    ");
14796                pw.print("oom: max="); pw.print(r.maxAdj);
14797                pw.print(" curRaw="); pw.print(r.curRawAdj);
14798                pw.print(" setRaw="); pw.print(r.setRawAdj);
14799                pw.print(" cur="); pw.print(r.curAdj);
14800                pw.print(" set="); pw.println(r.setAdj);
14801                pw.print(prefix);
14802                pw.print("    ");
14803                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14804                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14805                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14806                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14807                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14808                pw.println();
14809                pw.print(prefix);
14810                pw.print("    ");
14811                pw.print("cached="); pw.print(r.cached);
14812                pw.print(" empty="); pw.print(r.empty);
14813                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14814
14815                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14816                    if (r.lastWakeTime != 0) {
14817                        long wtime;
14818                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14819                        synchronized (stats) {
14820                            wtime = stats.getProcessWakeTime(r.info.uid,
14821                                    r.pid, curRealtime);
14822                        }
14823                        long timeUsed = wtime - r.lastWakeTime;
14824                        pw.print(prefix);
14825                        pw.print("    ");
14826                        pw.print("keep awake over ");
14827                        TimeUtils.formatDuration(realtimeSince, pw);
14828                        pw.print(" used ");
14829                        TimeUtils.formatDuration(timeUsed, pw);
14830                        pw.print(" (");
14831                        pw.print((timeUsed*100)/realtimeSince);
14832                        pw.println("%)");
14833                    }
14834                    if (r.lastCpuTime != 0) {
14835                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14836                        pw.print(prefix);
14837                        pw.print("    ");
14838                        pw.print("run cpu over ");
14839                        TimeUtils.formatDuration(uptimeSince, pw);
14840                        pw.print(" used ");
14841                        TimeUtils.formatDuration(timeUsed, pw);
14842                        pw.print(" (");
14843                        pw.print((timeUsed*100)/uptimeSince);
14844                        pw.println("%)");
14845                    }
14846                }
14847            }
14848        }
14849        return true;
14850    }
14851
14852    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14853            String[] args) {
14854        ArrayList<ProcessRecord> procs;
14855        synchronized (this) {
14856            if (args != null && args.length > start
14857                    && args[start].charAt(0) != '-') {
14858                procs = new ArrayList<ProcessRecord>();
14859                int pid = -1;
14860                try {
14861                    pid = Integer.parseInt(args[start]);
14862                } catch (NumberFormatException e) {
14863                }
14864                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14865                    ProcessRecord proc = mLruProcesses.get(i);
14866                    if (proc.pid == pid) {
14867                        procs.add(proc);
14868                    } else if (allPkgs && proc.pkgList != null
14869                            && proc.pkgList.containsKey(args[start])) {
14870                        procs.add(proc);
14871                    } else if (proc.processName.equals(args[start])) {
14872                        procs.add(proc);
14873                    }
14874                }
14875                if (procs.size() <= 0) {
14876                    return null;
14877                }
14878            } else {
14879                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14880            }
14881        }
14882        return procs;
14883    }
14884
14885    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14886            PrintWriter pw, String[] args) {
14887        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14888        if (procs == null) {
14889            pw.println("No process found for: " + args[0]);
14890            return;
14891        }
14892
14893        long uptime = SystemClock.uptimeMillis();
14894        long realtime = SystemClock.elapsedRealtime();
14895        pw.println("Applications Graphics Acceleration Info:");
14896        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14897
14898        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14899            ProcessRecord r = procs.get(i);
14900            if (r.thread != null) {
14901                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14902                pw.flush();
14903                try {
14904                    TransferPipe tp = new TransferPipe();
14905                    try {
14906                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14907                        tp.go(fd);
14908                    } finally {
14909                        tp.kill();
14910                    }
14911                } catch (IOException e) {
14912                    pw.println("Failure while dumping the app: " + r);
14913                    pw.flush();
14914                } catch (RemoteException e) {
14915                    pw.println("Got a RemoteException while dumping the app " + r);
14916                    pw.flush();
14917                }
14918            }
14919        }
14920    }
14921
14922    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14923        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14924        if (procs == null) {
14925            pw.println("No process found for: " + args[0]);
14926            return;
14927        }
14928
14929        pw.println("Applications Database Info:");
14930
14931        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14932            ProcessRecord r = procs.get(i);
14933            if (r.thread != null) {
14934                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14935                pw.flush();
14936                try {
14937                    TransferPipe tp = new TransferPipe();
14938                    try {
14939                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14940                        tp.go(fd);
14941                    } finally {
14942                        tp.kill();
14943                    }
14944                } catch (IOException e) {
14945                    pw.println("Failure while dumping the app: " + r);
14946                    pw.flush();
14947                } catch (RemoteException e) {
14948                    pw.println("Got a RemoteException while dumping the app " + r);
14949                    pw.flush();
14950                }
14951            }
14952        }
14953    }
14954
14955    final static class MemItem {
14956        final boolean isProc;
14957        final String label;
14958        final String shortLabel;
14959        final long pss;
14960        final long swapPss;
14961        final int id;
14962        final boolean hasActivities;
14963        ArrayList<MemItem> subitems;
14964
14965        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
14966                boolean _hasActivities) {
14967            isProc = true;
14968            label = _label;
14969            shortLabel = _shortLabel;
14970            pss = _pss;
14971            swapPss = _swapPss;
14972            id = _id;
14973            hasActivities = _hasActivities;
14974        }
14975
14976        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
14977            isProc = false;
14978            label = _label;
14979            shortLabel = _shortLabel;
14980            pss = _pss;
14981            swapPss = _swapPss;
14982            id = _id;
14983            hasActivities = false;
14984        }
14985    }
14986
14987    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14988            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
14989        if (sort && !isCompact) {
14990            Collections.sort(items, new Comparator<MemItem>() {
14991                @Override
14992                public int compare(MemItem lhs, MemItem rhs) {
14993                    if (lhs.pss < rhs.pss) {
14994                        return 1;
14995                    } else if (lhs.pss > rhs.pss) {
14996                        return -1;
14997                    }
14998                    return 0;
14999                }
15000            });
15001        }
15002
15003        for (int i=0; i<items.size(); i++) {
15004            MemItem mi = items.get(i);
15005            if (!isCompact) {
15006                if (dumpSwapPss) {
15007                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15008                            mi.label, stringifyKBSize(mi.swapPss));
15009                } else {
15010                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15011                }
15012            } else if (mi.isProc) {
15013                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15014                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15015                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15016                pw.println(mi.hasActivities ? ",a" : ",e");
15017            } else {
15018                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15019                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15020            }
15021            if (mi.subitems != null) {
15022                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15023                        true, isCompact, dumpSwapPss);
15024            }
15025        }
15026    }
15027
15028    // These are in KB.
15029    static final long[] DUMP_MEM_BUCKETS = new long[] {
15030        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15031        120*1024, 160*1024, 200*1024,
15032        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15033        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15034    };
15035
15036    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15037            boolean stackLike) {
15038        int start = label.lastIndexOf('.');
15039        if (start >= 0) start++;
15040        else start = 0;
15041        int end = label.length();
15042        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15043            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15044                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15045                out.append(bucket);
15046                out.append(stackLike ? "MB." : "MB ");
15047                out.append(label, start, end);
15048                return;
15049            }
15050        }
15051        out.append(memKB/1024);
15052        out.append(stackLike ? "MB." : "MB ");
15053        out.append(label, start, end);
15054    }
15055
15056    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15057            ProcessList.NATIVE_ADJ,
15058            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15059            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15060            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15061            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15062            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15063            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15064    };
15065    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15066            "Native",
15067            "System", "Persistent", "Persistent Service", "Foreground",
15068            "Visible", "Perceptible",
15069            "Heavy Weight", "Backup",
15070            "A Services", "Home",
15071            "Previous", "B Services", "Cached"
15072    };
15073    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15074            "native",
15075            "sys", "pers", "persvc", "fore",
15076            "vis", "percept",
15077            "heavy", "backup",
15078            "servicea", "home",
15079            "prev", "serviceb", "cached"
15080    };
15081
15082    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15083            long realtime, boolean isCheckinRequest, boolean isCompact) {
15084        if (isCompact) {
15085            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15086        }
15087        if (isCheckinRequest || isCompact) {
15088            // short checkin version
15089            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15090        } else {
15091            pw.println("Applications Memory Usage (in Kilobytes):");
15092            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15093        }
15094    }
15095
15096    private static final int KSM_SHARED = 0;
15097    private static final int KSM_SHARING = 1;
15098    private static final int KSM_UNSHARED = 2;
15099    private static final int KSM_VOLATILE = 3;
15100
15101    private final long[] getKsmInfo() {
15102        long[] longOut = new long[4];
15103        final int[] SINGLE_LONG_FORMAT = new int[] {
15104            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15105        };
15106        long[] longTmp = new long[1];
15107        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15108                SINGLE_LONG_FORMAT, null, longTmp, null);
15109        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15110        longTmp[0] = 0;
15111        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15112                SINGLE_LONG_FORMAT, null, longTmp, null);
15113        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15114        longTmp[0] = 0;
15115        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15116                SINGLE_LONG_FORMAT, null, longTmp, null);
15117        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15118        longTmp[0] = 0;
15119        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15120                SINGLE_LONG_FORMAT, null, longTmp, null);
15121        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15122        return longOut;
15123    }
15124
15125    private static String stringifySize(long size, int order) {
15126        Locale locale = Locale.US;
15127        switch (order) {
15128            case 1:
15129                return String.format(locale, "%,13d", size);
15130            case 1024:
15131                return String.format(locale, "%,9dK", size / 1024);
15132            case 1024 * 1024:
15133                return String.format(locale, "%,5dM", size / 1024 / 1024);
15134            case 1024 * 1024 * 1024:
15135                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15136            default:
15137                throw new IllegalArgumentException("Invalid size order");
15138        }
15139    }
15140
15141    private static String stringifyKBSize(long size) {
15142        return stringifySize(size * 1024, 1024);
15143    }
15144
15145    // Update this version number in case you change the 'compact' format
15146    private static final int MEMINFO_COMPACT_VERSION = 1;
15147
15148    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15149            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15150        boolean dumpDetails = false;
15151        boolean dumpFullDetails = false;
15152        boolean dumpDalvik = false;
15153        boolean dumpSummaryOnly = false;
15154        boolean oomOnly = false;
15155        boolean isCompact = false;
15156        boolean localOnly = false;
15157        boolean packages = false;
15158        boolean isCheckinRequest = false;
15159        boolean dumpSwapPss = false;
15160
15161        int opti = 0;
15162        while (opti < args.length) {
15163            String opt = args[opti];
15164            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15165                break;
15166            }
15167            opti++;
15168            if ("-a".equals(opt)) {
15169                dumpDetails = true;
15170                dumpFullDetails = true;
15171                dumpDalvik = true;
15172                dumpSwapPss = true;
15173            } else if ("-d".equals(opt)) {
15174                dumpDalvik = true;
15175            } else if ("-c".equals(opt)) {
15176                isCompact = true;
15177            } else if ("-s".equals(opt)) {
15178                dumpDetails = true;
15179                dumpSummaryOnly = true;
15180            } else if ("-S".equals(opt)) {
15181                dumpSwapPss = true;
15182            } else if ("--oom".equals(opt)) {
15183                oomOnly = true;
15184            } else if ("--local".equals(opt)) {
15185                localOnly = true;
15186            } else if ("--package".equals(opt)) {
15187                packages = true;
15188            } else if ("--checkin".equals(opt)) {
15189                isCheckinRequest = true;
15190
15191            } else if ("-h".equals(opt)) {
15192                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15193                pw.println("  -a: include all available information for each process.");
15194                pw.println("  -d: include dalvik details.");
15195                pw.println("  -c: dump in a compact machine-parseable representation.");
15196                pw.println("  -s: dump only summary of application memory usage.");
15197                pw.println("  -S: dump also SwapPss.");
15198                pw.println("  --oom: only show processes organized by oom adj.");
15199                pw.println("  --local: only collect details locally, don't call process.");
15200                pw.println("  --package: interpret process arg as package, dumping all");
15201                pw.println("             processes that have loaded that package.");
15202                pw.println("  --checkin: dump data for a checkin");
15203                pw.println("If [process] is specified it can be the name or ");
15204                pw.println("pid of a specific process to dump.");
15205                return;
15206            } else {
15207                pw.println("Unknown argument: " + opt + "; use -h for help");
15208            }
15209        }
15210
15211        long uptime = SystemClock.uptimeMillis();
15212        long realtime = SystemClock.elapsedRealtime();
15213        final long[] tmpLong = new long[1];
15214
15215        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15216        if (procs == null) {
15217            // No Java processes.  Maybe they want to print a native process.
15218            if (args != null && args.length > opti
15219                    && args[opti].charAt(0) != '-') {
15220                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15221                        = new ArrayList<ProcessCpuTracker.Stats>();
15222                updateCpuStatsNow();
15223                int findPid = -1;
15224                try {
15225                    findPid = Integer.parseInt(args[opti]);
15226                } catch (NumberFormatException e) {
15227                }
15228                synchronized (mProcessCpuTracker) {
15229                    final int N = mProcessCpuTracker.countStats();
15230                    for (int i=0; i<N; i++) {
15231                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15232                        if (st.pid == findPid || (st.baseName != null
15233                                && st.baseName.equals(args[opti]))) {
15234                            nativeProcs.add(st);
15235                        }
15236                    }
15237                }
15238                if (nativeProcs.size() > 0) {
15239                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15240                            isCompact);
15241                    Debug.MemoryInfo mi = null;
15242                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15243                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15244                        final int pid = r.pid;
15245                        if (!isCheckinRequest && dumpDetails) {
15246                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15247                        }
15248                        if (mi == null) {
15249                            mi = new Debug.MemoryInfo();
15250                        }
15251                        if (dumpDetails || (!brief && !oomOnly)) {
15252                            Debug.getMemoryInfo(pid, mi);
15253                        } else {
15254                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15255                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15256                        }
15257                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15258                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15259                        if (isCheckinRequest) {
15260                            pw.println();
15261                        }
15262                    }
15263                    return;
15264                }
15265            }
15266            pw.println("No process found for: " + args[opti]);
15267            return;
15268        }
15269
15270        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15271            dumpDetails = true;
15272        }
15273
15274        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15275
15276        String[] innerArgs = new String[args.length-opti];
15277        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15278
15279        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15280        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15281        long nativePss = 0;
15282        long nativeSwapPss = 0;
15283        long dalvikPss = 0;
15284        long dalvikSwapPss = 0;
15285        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15286                EmptyArray.LONG;
15287        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15288                EmptyArray.LONG;
15289        long otherPss = 0;
15290        long otherSwapPss = 0;
15291        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15292        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15293
15294        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15295        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15296        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15297                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15298
15299        long totalPss = 0;
15300        long totalSwapPss = 0;
15301        long cachedPss = 0;
15302        long cachedSwapPss = 0;
15303        boolean hasSwapPss = false;
15304
15305        Debug.MemoryInfo mi = null;
15306        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15307            final ProcessRecord r = procs.get(i);
15308            final IApplicationThread thread;
15309            final int pid;
15310            final int oomAdj;
15311            final boolean hasActivities;
15312            synchronized (this) {
15313                thread = r.thread;
15314                pid = r.pid;
15315                oomAdj = r.getSetAdjWithServices();
15316                hasActivities = r.activities.size() > 0;
15317            }
15318            if (thread != null) {
15319                if (!isCheckinRequest && dumpDetails) {
15320                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15321                }
15322                if (mi == null) {
15323                    mi = new Debug.MemoryInfo();
15324                }
15325                if (dumpDetails || (!brief && !oomOnly)) {
15326                    Debug.getMemoryInfo(pid, mi);
15327                    hasSwapPss = mi.hasSwappedOutPss;
15328                } else {
15329                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15330                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15331                }
15332                if (dumpDetails) {
15333                    if (localOnly) {
15334                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15335                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15336                        if (isCheckinRequest) {
15337                            pw.println();
15338                        }
15339                    } else {
15340                        try {
15341                            pw.flush();
15342                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15343                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15344                        } catch (RemoteException e) {
15345                            if (!isCheckinRequest) {
15346                                pw.println("Got RemoteException!");
15347                                pw.flush();
15348                            }
15349                        }
15350                    }
15351                }
15352
15353                final long myTotalPss = mi.getTotalPss();
15354                final long myTotalUss = mi.getTotalUss();
15355                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15356
15357                synchronized (this) {
15358                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15359                        // Record this for posterity if the process has been stable.
15360                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15361                    }
15362                }
15363
15364                if (!isCheckinRequest && mi != null) {
15365                    totalPss += myTotalPss;
15366                    totalSwapPss += myTotalSwapPss;
15367                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15368                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15369                            myTotalSwapPss, pid, hasActivities);
15370                    procMems.add(pssItem);
15371                    procMemsMap.put(pid, pssItem);
15372
15373                    nativePss += mi.nativePss;
15374                    nativeSwapPss += mi.nativeSwappedOutPss;
15375                    dalvikPss += mi.dalvikPss;
15376                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15377                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15378                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15379                        dalvikSubitemSwapPss[j] +=
15380                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15381                    }
15382                    otherPss += mi.otherPss;
15383                    otherSwapPss += mi.otherSwappedOutPss;
15384                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15385                        long mem = mi.getOtherPss(j);
15386                        miscPss[j] += mem;
15387                        otherPss -= mem;
15388                        mem = mi.getOtherSwappedOutPss(j);
15389                        miscSwapPss[j] += mem;
15390                        otherSwapPss -= mem;
15391                    }
15392
15393                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15394                        cachedPss += myTotalPss;
15395                        cachedSwapPss += myTotalSwapPss;
15396                    }
15397
15398                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15399                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15400                                || oomIndex == (oomPss.length-1)) {
15401                            oomPss[oomIndex] += myTotalPss;
15402                            oomSwapPss[oomIndex] += myTotalSwapPss;
15403                            if (oomProcs[oomIndex] == null) {
15404                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15405                            }
15406                            oomProcs[oomIndex].add(pssItem);
15407                            break;
15408                        }
15409                    }
15410                }
15411            }
15412        }
15413
15414        long nativeProcTotalPss = 0;
15415
15416        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15417            // If we are showing aggregations, also look for native processes to
15418            // include so that our aggregations are more accurate.
15419            updateCpuStatsNow();
15420            mi = null;
15421            synchronized (mProcessCpuTracker) {
15422                final int N = mProcessCpuTracker.countStats();
15423                for (int i=0; i<N; i++) {
15424                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15425                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15426                        if (mi == null) {
15427                            mi = new Debug.MemoryInfo();
15428                        }
15429                        if (!brief && !oomOnly) {
15430                            Debug.getMemoryInfo(st.pid, mi);
15431                        } else {
15432                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15433                            mi.nativePrivateDirty = (int)tmpLong[0];
15434                        }
15435
15436                        final long myTotalPss = mi.getTotalPss();
15437                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15438                        totalPss += myTotalPss;
15439                        nativeProcTotalPss += myTotalPss;
15440
15441                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15442                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15443                        procMems.add(pssItem);
15444
15445                        nativePss += mi.nativePss;
15446                        nativeSwapPss += mi.nativeSwappedOutPss;
15447                        dalvikPss += mi.dalvikPss;
15448                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15449                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15450                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15451                            dalvikSubitemSwapPss[j] +=
15452                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15453                        }
15454                        otherPss += mi.otherPss;
15455                        otherSwapPss += mi.otherSwappedOutPss;
15456                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15457                            long mem = mi.getOtherPss(j);
15458                            miscPss[j] += mem;
15459                            otherPss -= mem;
15460                            mem = mi.getOtherSwappedOutPss(j);
15461                            miscSwapPss[j] += mem;
15462                            otherSwapPss -= mem;
15463                        }
15464                        oomPss[0] += myTotalPss;
15465                        oomSwapPss[0] += myTotalSwapPss;
15466                        if (oomProcs[0] == null) {
15467                            oomProcs[0] = new ArrayList<MemItem>();
15468                        }
15469                        oomProcs[0].add(pssItem);
15470                    }
15471                }
15472            }
15473
15474            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15475
15476            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15477            final MemItem dalvikItem =
15478                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15479            if (dalvikSubitemPss.length > 0) {
15480                dalvikItem.subitems = new ArrayList<MemItem>();
15481                for (int j=0; j<dalvikSubitemPss.length; j++) {
15482                    final String name = Debug.MemoryInfo.getOtherLabel(
15483                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15484                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15485                                    dalvikSubitemSwapPss[j], j));
15486                }
15487            }
15488            catMems.add(dalvikItem);
15489            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15490            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15491                String label = Debug.MemoryInfo.getOtherLabel(j);
15492                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15493            }
15494
15495            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15496            for (int j=0; j<oomPss.length; j++) {
15497                if (oomPss[j] != 0) {
15498                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15499                            : DUMP_MEM_OOM_LABEL[j];
15500                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15501                            DUMP_MEM_OOM_ADJ[j]);
15502                    item.subitems = oomProcs[j];
15503                    oomMems.add(item);
15504                }
15505            }
15506
15507            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15508            if (!brief && !oomOnly && !isCompact) {
15509                pw.println();
15510                pw.println("Total PSS by process:");
15511                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15512                pw.println();
15513            }
15514            if (!isCompact) {
15515                pw.println("Total PSS by OOM adjustment:");
15516            }
15517            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15518            if (!brief && !oomOnly) {
15519                PrintWriter out = categoryPw != null ? categoryPw : pw;
15520                if (!isCompact) {
15521                    out.println();
15522                    out.println("Total PSS by category:");
15523                }
15524                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15525            }
15526            if (!isCompact) {
15527                pw.println();
15528            }
15529            MemInfoReader memInfo = new MemInfoReader();
15530            memInfo.readMemInfo();
15531            if (nativeProcTotalPss > 0) {
15532                synchronized (this) {
15533                    final long cachedKb = memInfo.getCachedSizeKb();
15534                    final long freeKb = memInfo.getFreeSizeKb();
15535                    final long zramKb = memInfo.getZramTotalSizeKb();
15536                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15537                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15538                            kernelKb*1024, nativeProcTotalPss*1024);
15539                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15540                            nativeProcTotalPss);
15541                }
15542            }
15543            if (!brief) {
15544                if (!isCompact) {
15545                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15546                    pw.print(" (status ");
15547                    switch (mLastMemoryLevel) {
15548                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15549                            pw.println("normal)");
15550                            break;
15551                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15552                            pw.println("moderate)");
15553                            break;
15554                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15555                            pw.println("low)");
15556                            break;
15557                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15558                            pw.println("critical)");
15559                            break;
15560                        default:
15561                            pw.print(mLastMemoryLevel);
15562                            pw.println(")");
15563                            break;
15564                    }
15565                    pw.print(" Free RAM: ");
15566                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15567                            + memInfo.getFreeSizeKb()));
15568                    pw.print(" (");
15569                    pw.print(stringifyKBSize(cachedPss));
15570                    pw.print(" cached pss + ");
15571                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15572                    pw.print(" cached kernel + ");
15573                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15574                    pw.println(" free)");
15575                } else {
15576                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15577                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15578                            + memInfo.getFreeSizeKb()); pw.print(",");
15579                    pw.println(totalPss - cachedPss);
15580                }
15581            }
15582            long lostRAM = memInfo.getTotalSizeKb()
15583                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15584                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15585            if (!isCompact) {
15586                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15587                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15588                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15589                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15590                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15591            } else {
15592                pw.print("lostram,"); pw.println(lostRAM);
15593            }
15594            if (!brief) {
15595                if (memInfo.getZramTotalSizeKb() != 0) {
15596                    if (!isCompact) {
15597                        pw.print("     ZRAM: ");
15598                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15599                                pw.print(" physical used for ");
15600                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15601                                        - memInfo.getSwapFreeSizeKb()));
15602                                pw.print(" in swap (");
15603                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15604                                pw.println(" total swap)");
15605                    } else {
15606                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15607                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15608                                pw.println(memInfo.getSwapFreeSizeKb());
15609                    }
15610                }
15611                final long[] ksm = getKsmInfo();
15612                if (!isCompact) {
15613                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15614                            || ksm[KSM_VOLATILE] != 0) {
15615                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15616                                pw.print(" saved from shared ");
15617                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15618                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15619                                pw.print(" unshared; ");
15620                                pw.print(stringifyKBSize(
15621                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15622                    }
15623                    pw.print("   Tuning: ");
15624                    pw.print(ActivityManager.staticGetMemoryClass());
15625                    pw.print(" (large ");
15626                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15627                    pw.print("), oom ");
15628                    pw.print(stringifySize(
15629                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15630                    pw.print(", restore limit ");
15631                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15632                    if (ActivityManager.isLowRamDeviceStatic()) {
15633                        pw.print(" (low-ram)");
15634                    }
15635                    if (ActivityManager.isHighEndGfx()) {
15636                        pw.print(" (high-end-gfx)");
15637                    }
15638                    pw.println();
15639                } else {
15640                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15641                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15642                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15643                    pw.print("tuning,");
15644                    pw.print(ActivityManager.staticGetMemoryClass());
15645                    pw.print(',');
15646                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15647                    pw.print(',');
15648                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15649                    if (ActivityManager.isLowRamDeviceStatic()) {
15650                        pw.print(",low-ram");
15651                    }
15652                    if (ActivityManager.isHighEndGfx()) {
15653                        pw.print(",high-end-gfx");
15654                    }
15655                    pw.println();
15656                }
15657            }
15658        }
15659    }
15660
15661    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15662            long memtrack, String name) {
15663        sb.append("  ");
15664        sb.append(ProcessList.makeOomAdjString(oomAdj));
15665        sb.append(' ');
15666        sb.append(ProcessList.makeProcStateString(procState));
15667        sb.append(' ');
15668        ProcessList.appendRamKb(sb, pss);
15669        sb.append(": ");
15670        sb.append(name);
15671        if (memtrack > 0) {
15672            sb.append(" (");
15673            sb.append(stringifyKBSize(memtrack));
15674            sb.append(" memtrack)");
15675        }
15676    }
15677
15678    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15679        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15680        sb.append(" (pid ");
15681        sb.append(mi.pid);
15682        sb.append(") ");
15683        sb.append(mi.adjType);
15684        sb.append('\n');
15685        if (mi.adjReason != null) {
15686            sb.append("                      ");
15687            sb.append(mi.adjReason);
15688            sb.append('\n');
15689        }
15690    }
15691
15692    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15693        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15694        for (int i=0, N=memInfos.size(); i<N; i++) {
15695            ProcessMemInfo mi = memInfos.get(i);
15696            infoMap.put(mi.pid, mi);
15697        }
15698        updateCpuStatsNow();
15699        long[] memtrackTmp = new long[1];
15700        synchronized (mProcessCpuTracker) {
15701            final int N = mProcessCpuTracker.countStats();
15702            for (int i=0; i<N; i++) {
15703                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15704                if (st.vsize > 0) {
15705                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15706                    if (pss > 0) {
15707                        if (infoMap.indexOfKey(st.pid) < 0) {
15708                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15709                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15710                            mi.pss = pss;
15711                            mi.memtrack = memtrackTmp[0];
15712                            memInfos.add(mi);
15713                        }
15714                    }
15715                }
15716            }
15717        }
15718
15719        long totalPss = 0;
15720        long totalMemtrack = 0;
15721        for (int i=0, N=memInfos.size(); i<N; i++) {
15722            ProcessMemInfo mi = memInfos.get(i);
15723            if (mi.pss == 0) {
15724                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15725                mi.memtrack = memtrackTmp[0];
15726            }
15727            totalPss += mi.pss;
15728            totalMemtrack += mi.memtrack;
15729        }
15730        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15731            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15732                if (lhs.oomAdj != rhs.oomAdj) {
15733                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15734                }
15735                if (lhs.pss != rhs.pss) {
15736                    return lhs.pss < rhs.pss ? 1 : -1;
15737                }
15738                return 0;
15739            }
15740        });
15741
15742        StringBuilder tag = new StringBuilder(128);
15743        StringBuilder stack = new StringBuilder(128);
15744        tag.append("Low on memory -- ");
15745        appendMemBucket(tag, totalPss, "total", false);
15746        appendMemBucket(stack, totalPss, "total", true);
15747
15748        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15749        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15750        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15751
15752        boolean firstLine = true;
15753        int lastOomAdj = Integer.MIN_VALUE;
15754        long extraNativeRam = 0;
15755        long extraNativeMemtrack = 0;
15756        long cachedPss = 0;
15757        for (int i=0, N=memInfos.size(); i<N; i++) {
15758            ProcessMemInfo mi = memInfos.get(i);
15759
15760            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15761                cachedPss += mi.pss;
15762            }
15763
15764            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15765                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15766                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15767                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15768                if (lastOomAdj != mi.oomAdj) {
15769                    lastOomAdj = mi.oomAdj;
15770                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15771                        tag.append(" / ");
15772                    }
15773                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15774                        if (firstLine) {
15775                            stack.append(":");
15776                            firstLine = false;
15777                        }
15778                        stack.append("\n\t at ");
15779                    } else {
15780                        stack.append("$");
15781                    }
15782                } else {
15783                    tag.append(" ");
15784                    stack.append("$");
15785                }
15786                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15787                    appendMemBucket(tag, mi.pss, mi.name, false);
15788                }
15789                appendMemBucket(stack, mi.pss, mi.name, true);
15790                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15791                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15792                    stack.append("(");
15793                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15794                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15795                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15796                            stack.append(":");
15797                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15798                        }
15799                    }
15800                    stack.append(")");
15801                }
15802            }
15803
15804            appendMemInfo(fullNativeBuilder, mi);
15805            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15806                // The short form only has native processes that are >= 512K.
15807                if (mi.pss >= 512) {
15808                    appendMemInfo(shortNativeBuilder, mi);
15809                } else {
15810                    extraNativeRam += mi.pss;
15811                    extraNativeMemtrack += mi.memtrack;
15812                }
15813            } else {
15814                // Short form has all other details, but if we have collected RAM
15815                // from smaller native processes let's dump a summary of that.
15816                if (extraNativeRam > 0) {
15817                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15818                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15819                    shortNativeBuilder.append('\n');
15820                    extraNativeRam = 0;
15821                }
15822                appendMemInfo(fullJavaBuilder, mi);
15823            }
15824        }
15825
15826        fullJavaBuilder.append("           ");
15827        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15828        fullJavaBuilder.append(": TOTAL");
15829        if (totalMemtrack > 0) {
15830            fullJavaBuilder.append(" (");
15831            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15832            fullJavaBuilder.append(" memtrack)");
15833        } else {
15834        }
15835        fullJavaBuilder.append("\n");
15836
15837        MemInfoReader memInfo = new MemInfoReader();
15838        memInfo.readMemInfo();
15839        final long[] infos = memInfo.getRawInfo();
15840
15841        StringBuilder memInfoBuilder = new StringBuilder(1024);
15842        Debug.getMemInfo(infos);
15843        memInfoBuilder.append("  MemInfo: ");
15844        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15845        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15846        memInfoBuilder.append(stringifyKBSize(
15847                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15848        memInfoBuilder.append(stringifyKBSize(
15849                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15850        memInfoBuilder.append(stringifyKBSize(
15851                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15852        memInfoBuilder.append("           ");
15853        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15854        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15855        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15856        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15857        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15858            memInfoBuilder.append("  ZRAM: ");
15859            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15860            memInfoBuilder.append(" RAM, ");
15861            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15862            memInfoBuilder.append(" swap total, ");
15863            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15864            memInfoBuilder.append(" swap free\n");
15865        }
15866        final long[] ksm = getKsmInfo();
15867        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15868                || ksm[KSM_VOLATILE] != 0) {
15869            memInfoBuilder.append("  KSM: ");
15870            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15871            memInfoBuilder.append(" saved from shared ");
15872            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15873            memInfoBuilder.append("\n       ");
15874            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15875            memInfoBuilder.append(" unshared; ");
15876            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15877            memInfoBuilder.append(" volatile\n");
15878        }
15879        memInfoBuilder.append("  Free RAM: ");
15880        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15881                + memInfo.getFreeSizeKb()));
15882        memInfoBuilder.append("\n");
15883        memInfoBuilder.append("  Used RAM: ");
15884        memInfoBuilder.append(stringifyKBSize(
15885                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15886        memInfoBuilder.append("\n");
15887        memInfoBuilder.append("  Lost RAM: ");
15888        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15889                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15890                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15891        memInfoBuilder.append("\n");
15892        Slog.i(TAG, "Low on memory:");
15893        Slog.i(TAG, shortNativeBuilder.toString());
15894        Slog.i(TAG, fullJavaBuilder.toString());
15895        Slog.i(TAG, memInfoBuilder.toString());
15896
15897        StringBuilder dropBuilder = new StringBuilder(1024);
15898        /*
15899        StringWriter oomSw = new StringWriter();
15900        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15901        StringWriter catSw = new StringWriter();
15902        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15903        String[] emptyArgs = new String[] { };
15904        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15905        oomPw.flush();
15906        String oomString = oomSw.toString();
15907        */
15908        dropBuilder.append("Low on memory:");
15909        dropBuilder.append(stack);
15910        dropBuilder.append('\n');
15911        dropBuilder.append(fullNativeBuilder);
15912        dropBuilder.append(fullJavaBuilder);
15913        dropBuilder.append('\n');
15914        dropBuilder.append(memInfoBuilder);
15915        dropBuilder.append('\n');
15916        /*
15917        dropBuilder.append(oomString);
15918        dropBuilder.append('\n');
15919        */
15920        StringWriter catSw = new StringWriter();
15921        synchronized (ActivityManagerService.this) {
15922            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15923            String[] emptyArgs = new String[] { };
15924            catPw.println();
15925            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15926            catPw.println();
15927            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15928                    false, false, null);
15929            catPw.println();
15930            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15931            catPw.flush();
15932        }
15933        dropBuilder.append(catSw.toString());
15934        addErrorToDropBox("lowmem", null, "system_server", null,
15935                null, tag.toString(), dropBuilder.toString(), null, null);
15936        //Slog.i(TAG, "Sent to dropbox:");
15937        //Slog.i(TAG, dropBuilder.toString());
15938        synchronized (ActivityManagerService.this) {
15939            long now = SystemClock.uptimeMillis();
15940            if (mLastMemUsageReportTime < now) {
15941                mLastMemUsageReportTime = now;
15942            }
15943        }
15944    }
15945
15946    /**
15947     * Searches array of arguments for the specified string
15948     * @param args array of argument strings
15949     * @param value value to search for
15950     * @return true if the value is contained in the array
15951     */
15952    private static boolean scanArgs(String[] args, String value) {
15953        if (args != null) {
15954            for (String arg : args) {
15955                if (value.equals(arg)) {
15956                    return true;
15957                }
15958            }
15959        }
15960        return false;
15961    }
15962
15963    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15964            ContentProviderRecord cpr, boolean always) {
15965        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15966
15967        if (!inLaunching || always) {
15968            synchronized (cpr) {
15969                cpr.launchingApp = null;
15970                cpr.notifyAll();
15971            }
15972            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15973            String names[] = cpr.info.authority.split(";");
15974            for (int j = 0; j < names.length; j++) {
15975                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15976            }
15977        }
15978
15979        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15980            ContentProviderConnection conn = cpr.connections.get(i);
15981            if (conn.waiting) {
15982                // If this connection is waiting for the provider, then we don't
15983                // need to mess with its process unless we are always removing
15984                // or for some reason the provider is not currently launching.
15985                if (inLaunching && !always) {
15986                    continue;
15987                }
15988            }
15989            ProcessRecord capp = conn.client;
15990            conn.dead = true;
15991            if (conn.stableCount > 0) {
15992                if (!capp.persistent && capp.thread != null
15993                        && capp.pid != 0
15994                        && capp.pid != MY_PID) {
15995                    capp.kill("depends on provider "
15996                            + cpr.name.flattenToShortString()
15997                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15998                }
15999            } else if (capp.thread != null && conn.provider.provider != null) {
16000                try {
16001                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16002                } catch (RemoteException e) {
16003                }
16004                // In the protocol here, we don't expect the client to correctly
16005                // clean up this connection, we'll just remove it.
16006                cpr.connections.remove(i);
16007                if (conn.client.conProviders.remove(conn)) {
16008                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16009                }
16010            }
16011        }
16012
16013        if (inLaunching && always) {
16014            mLaunchingProviders.remove(cpr);
16015        }
16016        return inLaunching;
16017    }
16018
16019    /**
16020     * Main code for cleaning up a process when it has gone away.  This is
16021     * called both as a result of the process dying, or directly when stopping
16022     * a process when running in single process mode.
16023     *
16024     * @return Returns true if the given process has been restarted, so the
16025     * app that was passed in must remain on the process lists.
16026     */
16027    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16028            boolean restarting, boolean allowRestart, int index) {
16029        if (index >= 0) {
16030            removeLruProcessLocked(app);
16031            ProcessList.remove(app.pid);
16032        }
16033
16034        mProcessesToGc.remove(app);
16035        mPendingPssProcesses.remove(app);
16036
16037        // Dismiss any open dialogs.
16038        if (app.crashDialog != null && !app.forceCrashReport) {
16039            app.crashDialog.dismiss();
16040            app.crashDialog = null;
16041        }
16042        if (app.anrDialog != null) {
16043            app.anrDialog.dismiss();
16044            app.anrDialog = null;
16045        }
16046        if (app.waitDialog != null) {
16047            app.waitDialog.dismiss();
16048            app.waitDialog = null;
16049        }
16050
16051        app.crashing = false;
16052        app.notResponding = false;
16053
16054        app.resetPackageList(mProcessStats);
16055        app.unlinkDeathRecipient();
16056        app.makeInactive(mProcessStats);
16057        app.waitingToKill = null;
16058        app.forcingToForeground = null;
16059        updateProcessForegroundLocked(app, false, false);
16060        app.foregroundActivities = false;
16061        app.hasShownUi = false;
16062        app.treatLikeActivity = false;
16063        app.hasAboveClient = false;
16064        app.hasClientActivities = false;
16065
16066        mServices.killServicesLocked(app, allowRestart);
16067
16068        boolean restart = false;
16069
16070        // Remove published content providers.
16071        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16072            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16073            final boolean always = app.bad || !allowRestart;
16074            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16075            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16076                // We left the provider in the launching list, need to
16077                // restart it.
16078                restart = true;
16079            }
16080
16081            cpr.provider = null;
16082            cpr.proc = null;
16083        }
16084        app.pubProviders.clear();
16085
16086        // Take care of any launching providers waiting for this process.
16087        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16088            restart = true;
16089        }
16090
16091        // Unregister from connected content providers.
16092        if (!app.conProviders.isEmpty()) {
16093            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16094                ContentProviderConnection conn = app.conProviders.get(i);
16095                conn.provider.connections.remove(conn);
16096                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16097                        conn.provider.name);
16098            }
16099            app.conProviders.clear();
16100        }
16101
16102        // At this point there may be remaining entries in mLaunchingProviders
16103        // where we were the only one waiting, so they are no longer of use.
16104        // Look for these and clean up if found.
16105        // XXX Commented out for now.  Trying to figure out a way to reproduce
16106        // the actual situation to identify what is actually going on.
16107        if (false) {
16108            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16109                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16110                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16111                    synchronized (cpr) {
16112                        cpr.launchingApp = null;
16113                        cpr.notifyAll();
16114                    }
16115                }
16116            }
16117        }
16118
16119        skipCurrentReceiverLocked(app);
16120
16121        // Unregister any receivers.
16122        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16123            removeReceiverLocked(app.receivers.valueAt(i));
16124        }
16125        app.receivers.clear();
16126
16127        // If the app is undergoing backup, tell the backup manager about it
16128        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16129            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16130                    + mBackupTarget.appInfo + " died during backup");
16131            try {
16132                IBackupManager bm = IBackupManager.Stub.asInterface(
16133                        ServiceManager.getService(Context.BACKUP_SERVICE));
16134                bm.agentDisconnected(app.info.packageName);
16135            } catch (RemoteException e) {
16136                // can't happen; backup manager is local
16137            }
16138        }
16139
16140        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16141            ProcessChangeItem item = mPendingProcessChanges.get(i);
16142            if (item.pid == app.pid) {
16143                mPendingProcessChanges.remove(i);
16144                mAvailProcessChanges.add(item);
16145            }
16146        }
16147        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16148                null).sendToTarget();
16149
16150        // If the caller is restarting this app, then leave it in its
16151        // current lists and let the caller take care of it.
16152        if (restarting) {
16153            return false;
16154        }
16155
16156        if (!app.persistent || app.isolated) {
16157            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16158                    "Removing non-persistent process during cleanup: " + app);
16159            removeProcessNameLocked(app.processName, app.uid);
16160            if (mHeavyWeightProcess == app) {
16161                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16162                        mHeavyWeightProcess.userId, 0));
16163                mHeavyWeightProcess = null;
16164            }
16165        } else if (!app.removed) {
16166            // This app is persistent, so we need to keep its record around.
16167            // If it is not already on the pending app list, add it there
16168            // and start a new process for it.
16169            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16170                mPersistentStartingProcesses.add(app);
16171                restart = true;
16172            }
16173        }
16174        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16175                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16176        mProcessesOnHold.remove(app);
16177
16178        if (app == mHomeProcess) {
16179            mHomeProcess = null;
16180        }
16181        if (app == mPreviousProcess) {
16182            mPreviousProcess = null;
16183        }
16184
16185        if (restart && !app.isolated) {
16186            // We have components that still need to be running in the
16187            // process, so re-launch it.
16188            if (index < 0) {
16189                ProcessList.remove(app.pid);
16190            }
16191            addProcessNameLocked(app);
16192            startProcessLocked(app, "restart", app.processName);
16193            return true;
16194        } else if (app.pid > 0 && app.pid != MY_PID) {
16195            // Goodbye!
16196            boolean removed;
16197            synchronized (mPidsSelfLocked) {
16198                mPidsSelfLocked.remove(app.pid);
16199                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16200            }
16201            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16202            if (app.isolated) {
16203                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16204            }
16205            app.setPid(0);
16206        }
16207        return false;
16208    }
16209
16210    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16211        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16212            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16213            if (cpr.launchingApp == app) {
16214                return true;
16215            }
16216        }
16217        return false;
16218    }
16219
16220    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16221        // Look through the content providers we are waiting to have launched,
16222        // and if any run in this process then either schedule a restart of
16223        // the process or kill the client waiting for it if this process has
16224        // gone bad.
16225        boolean restart = false;
16226        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16227            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16228            if (cpr.launchingApp == app) {
16229                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16230                    restart = true;
16231                } else {
16232                    removeDyingProviderLocked(app, cpr, true);
16233                }
16234            }
16235        }
16236        return restart;
16237    }
16238
16239    // =========================================================
16240    // SERVICES
16241    // =========================================================
16242
16243    @Override
16244    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16245            int flags) {
16246        enforceNotIsolatedCaller("getServices");
16247        synchronized (this) {
16248            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16249        }
16250    }
16251
16252    @Override
16253    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16254        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16255        synchronized (this) {
16256            return mServices.getRunningServiceControlPanelLocked(name);
16257        }
16258    }
16259
16260    @Override
16261    public ComponentName startService(IApplicationThread caller, Intent service,
16262            String resolvedType, String callingPackage, int userId)
16263            throws TransactionTooLargeException {
16264        enforceNotIsolatedCaller("startService");
16265        // Refuse possible leaked file descriptors
16266        if (service != null && service.hasFileDescriptors() == true) {
16267            throw new IllegalArgumentException("File descriptors passed in Intent");
16268        }
16269
16270        if (callingPackage == null) {
16271            throw new IllegalArgumentException("callingPackage cannot be null");
16272        }
16273
16274        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16275                "startService: " + service + " type=" + resolvedType);
16276        synchronized(this) {
16277            final int callingPid = Binder.getCallingPid();
16278            final int callingUid = Binder.getCallingUid();
16279            final long origId = Binder.clearCallingIdentity();
16280            ComponentName res = mServices.startServiceLocked(caller, service,
16281                    resolvedType, callingPid, callingUid, callingPackage, userId);
16282            Binder.restoreCallingIdentity(origId);
16283            return res;
16284        }
16285    }
16286
16287    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16288            String callingPackage, int userId)
16289            throws TransactionTooLargeException {
16290        synchronized(this) {
16291            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16292                    "startServiceInPackage: " + service + " type=" + resolvedType);
16293            final long origId = Binder.clearCallingIdentity();
16294            ComponentName res = mServices.startServiceLocked(null, service,
16295                    resolvedType, -1, uid, callingPackage, userId);
16296            Binder.restoreCallingIdentity(origId);
16297            return res;
16298        }
16299    }
16300
16301    @Override
16302    public int stopService(IApplicationThread caller, Intent service,
16303            String resolvedType, int userId) {
16304        enforceNotIsolatedCaller("stopService");
16305        // Refuse possible leaked file descriptors
16306        if (service != null && service.hasFileDescriptors() == true) {
16307            throw new IllegalArgumentException("File descriptors passed in Intent");
16308        }
16309
16310        synchronized(this) {
16311            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16312        }
16313    }
16314
16315    @Override
16316    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16317        enforceNotIsolatedCaller("peekService");
16318        // Refuse possible leaked file descriptors
16319        if (service != null && service.hasFileDescriptors() == true) {
16320            throw new IllegalArgumentException("File descriptors passed in Intent");
16321        }
16322
16323        if (callingPackage == null) {
16324            throw new IllegalArgumentException("callingPackage cannot be null");
16325        }
16326
16327        synchronized(this) {
16328            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16329        }
16330    }
16331
16332    @Override
16333    public boolean stopServiceToken(ComponentName className, IBinder token,
16334            int startId) {
16335        synchronized(this) {
16336            return mServices.stopServiceTokenLocked(className, token, startId);
16337        }
16338    }
16339
16340    @Override
16341    public void setServiceForeground(ComponentName className, IBinder token,
16342            int id, Notification notification, boolean removeNotification) {
16343        synchronized(this) {
16344            mServices.setServiceForegroundLocked(className, token, id, notification,
16345                    removeNotification);
16346        }
16347    }
16348
16349    @Override
16350    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16351            boolean requireFull, String name, String callerPackage) {
16352        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16353                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16354    }
16355
16356    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16357            String className, int flags) {
16358        boolean result = false;
16359        // For apps that don't have pre-defined UIDs, check for permission
16360        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16361            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16362                if (ActivityManager.checkUidPermission(
16363                        INTERACT_ACROSS_USERS,
16364                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16365                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16366                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16367                            + " requests FLAG_SINGLE_USER, but app does not hold "
16368                            + INTERACT_ACROSS_USERS;
16369                    Slog.w(TAG, msg);
16370                    throw new SecurityException(msg);
16371                }
16372                // Permission passed
16373                result = true;
16374            }
16375        } else if ("system".equals(componentProcessName)) {
16376            result = true;
16377        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16378            // Phone app and persistent apps are allowed to export singleuser providers.
16379            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16380                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16381        }
16382        if (DEBUG_MU) Slog.v(TAG_MU,
16383                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16384                + Integer.toHexString(flags) + ") = " + result);
16385        return result;
16386    }
16387
16388    /**
16389     * Checks to see if the caller is in the same app as the singleton
16390     * component, or the component is in a special app. It allows special apps
16391     * to export singleton components but prevents exporting singleton
16392     * components for regular apps.
16393     */
16394    boolean isValidSingletonCall(int callingUid, int componentUid) {
16395        int componentAppId = UserHandle.getAppId(componentUid);
16396        return UserHandle.isSameApp(callingUid, componentUid)
16397                || componentAppId == Process.SYSTEM_UID
16398                || componentAppId == Process.PHONE_UID
16399                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16400                        == PackageManager.PERMISSION_GRANTED;
16401    }
16402
16403    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16404            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16405            int userId) throws TransactionTooLargeException {
16406        enforceNotIsolatedCaller("bindService");
16407
16408        // Refuse possible leaked file descriptors
16409        if (service != null && service.hasFileDescriptors() == true) {
16410            throw new IllegalArgumentException("File descriptors passed in Intent");
16411        }
16412
16413        if (callingPackage == null) {
16414            throw new IllegalArgumentException("callingPackage cannot be null");
16415        }
16416
16417        synchronized(this) {
16418            return mServices.bindServiceLocked(caller, token, service,
16419                    resolvedType, connection, flags, callingPackage, userId);
16420        }
16421    }
16422
16423    public boolean unbindService(IServiceConnection connection) {
16424        synchronized (this) {
16425            return mServices.unbindServiceLocked(connection);
16426        }
16427    }
16428
16429    public void publishService(IBinder token, Intent intent, IBinder service) {
16430        // Refuse possible leaked file descriptors
16431        if (intent != null && intent.hasFileDescriptors() == true) {
16432            throw new IllegalArgumentException("File descriptors passed in Intent");
16433        }
16434
16435        synchronized(this) {
16436            if (!(token instanceof ServiceRecord)) {
16437                throw new IllegalArgumentException("Invalid service token");
16438            }
16439            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16440        }
16441    }
16442
16443    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16444        // Refuse possible leaked file descriptors
16445        if (intent != null && intent.hasFileDescriptors() == true) {
16446            throw new IllegalArgumentException("File descriptors passed in Intent");
16447        }
16448
16449        synchronized(this) {
16450            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16451        }
16452    }
16453
16454    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16455        synchronized(this) {
16456            if (!(token instanceof ServiceRecord)) {
16457                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16458                throw new IllegalArgumentException("Invalid service token");
16459            }
16460            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16461        }
16462    }
16463
16464    // =========================================================
16465    // BACKUP AND RESTORE
16466    // =========================================================
16467
16468    // Cause the target app to be launched if necessary and its backup agent
16469    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16470    // activity manager to announce its creation.
16471    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16472        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16473                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16474        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16475
16476        synchronized(this) {
16477            // !!! TODO: currently no check here that we're already bound
16478            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16479            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16480            synchronized (stats) {
16481                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16482            }
16483
16484            // Backup agent is now in use, its package can't be stopped.
16485            try {
16486                AppGlobals.getPackageManager().setPackageStoppedState(
16487                        app.packageName, false, UserHandle.getUserId(app.uid));
16488            } catch (RemoteException e) {
16489            } catch (IllegalArgumentException e) {
16490                Slog.w(TAG, "Failed trying to unstop package "
16491                        + app.packageName + ": " + e);
16492            }
16493
16494            BackupRecord r = new BackupRecord(ss, app, backupMode);
16495            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16496                    ? new ComponentName(app.packageName, app.backupAgentName)
16497                    : new ComponentName("android", "FullBackupAgent");
16498            // startProcessLocked() returns existing proc's record if it's already running
16499            ProcessRecord proc = startProcessLocked(app.processName, app,
16500                    false, 0, "backup", hostingName, false, false, false);
16501            if (proc == null) {
16502                Slog.e(TAG, "Unable to start backup agent process " + r);
16503                return false;
16504            }
16505
16506            r.app = proc;
16507            mBackupTarget = r;
16508            mBackupAppName = app.packageName;
16509
16510            // Try not to kill the process during backup
16511            updateOomAdjLocked(proc);
16512
16513            // If the process is already attached, schedule the creation of the backup agent now.
16514            // If it is not yet live, this will be done when it attaches to the framework.
16515            if (proc.thread != null) {
16516                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16517                try {
16518                    proc.thread.scheduleCreateBackupAgent(app,
16519                            compatibilityInfoForPackageLocked(app), backupMode);
16520                } catch (RemoteException e) {
16521                    // Will time out on the backup manager side
16522                }
16523            } else {
16524                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16525            }
16526            // Invariants: at this point, the target app process exists and the application
16527            // is either already running or in the process of coming up.  mBackupTarget and
16528            // mBackupAppName describe the app, so that when it binds back to the AM we
16529            // know that it's scheduled for a backup-agent operation.
16530        }
16531
16532        return true;
16533    }
16534
16535    @Override
16536    public void clearPendingBackup() {
16537        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16538        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16539
16540        synchronized (this) {
16541            mBackupTarget = null;
16542            mBackupAppName = null;
16543        }
16544    }
16545
16546    // A backup agent has just come up
16547    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16548        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16549                + " = " + agent);
16550
16551        synchronized(this) {
16552            if (!agentPackageName.equals(mBackupAppName)) {
16553                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16554                return;
16555            }
16556        }
16557
16558        long oldIdent = Binder.clearCallingIdentity();
16559        try {
16560            IBackupManager bm = IBackupManager.Stub.asInterface(
16561                    ServiceManager.getService(Context.BACKUP_SERVICE));
16562            bm.agentConnected(agentPackageName, agent);
16563        } catch (RemoteException e) {
16564            // can't happen; the backup manager service is local
16565        } catch (Exception e) {
16566            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16567            e.printStackTrace();
16568        } finally {
16569            Binder.restoreCallingIdentity(oldIdent);
16570        }
16571    }
16572
16573    // done with this agent
16574    public void unbindBackupAgent(ApplicationInfo appInfo) {
16575        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16576        if (appInfo == null) {
16577            Slog.w(TAG, "unbind backup agent for null app");
16578            return;
16579        }
16580
16581        synchronized(this) {
16582            try {
16583                if (mBackupAppName == null) {
16584                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16585                    return;
16586                }
16587
16588                if (!mBackupAppName.equals(appInfo.packageName)) {
16589                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16590                    return;
16591                }
16592
16593                // Not backing this app up any more; reset its OOM adjustment
16594                final ProcessRecord proc = mBackupTarget.app;
16595                updateOomAdjLocked(proc);
16596
16597                // If the app crashed during backup, 'thread' will be null here
16598                if (proc.thread != null) {
16599                    try {
16600                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16601                                compatibilityInfoForPackageLocked(appInfo));
16602                    } catch (Exception e) {
16603                        Slog.e(TAG, "Exception when unbinding backup agent:");
16604                        e.printStackTrace();
16605                    }
16606                }
16607            } finally {
16608                mBackupTarget = null;
16609                mBackupAppName = null;
16610            }
16611        }
16612    }
16613    // =========================================================
16614    // BROADCASTS
16615    // =========================================================
16616
16617    boolean isPendingBroadcastProcessLocked(int pid) {
16618        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16619                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16620    }
16621
16622    void skipPendingBroadcastLocked(int pid) {
16623            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16624            for (BroadcastQueue queue : mBroadcastQueues) {
16625                queue.skipPendingBroadcastLocked(pid);
16626            }
16627    }
16628
16629    // The app just attached; send any pending broadcasts that it should receive
16630    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16631        boolean didSomething = false;
16632        for (BroadcastQueue queue : mBroadcastQueues) {
16633            didSomething |= queue.sendPendingBroadcastsLocked(app);
16634        }
16635        return didSomething;
16636    }
16637
16638    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16639            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16640        enforceNotIsolatedCaller("registerReceiver");
16641        ArrayList<Intent> stickyIntents = null;
16642        ProcessRecord callerApp = null;
16643        int callingUid;
16644        int callingPid;
16645        synchronized(this) {
16646            if (caller != null) {
16647                callerApp = getRecordForAppLocked(caller);
16648                if (callerApp == null) {
16649                    throw new SecurityException(
16650                            "Unable to find app for caller " + caller
16651                            + " (pid=" + Binder.getCallingPid()
16652                            + ") when registering receiver " + receiver);
16653                }
16654                if (callerApp.info.uid != Process.SYSTEM_UID &&
16655                        !callerApp.pkgList.containsKey(callerPackage) &&
16656                        !"android".equals(callerPackage)) {
16657                    throw new SecurityException("Given caller package " + callerPackage
16658                            + " is not running in process " + callerApp);
16659                }
16660                callingUid = callerApp.info.uid;
16661                callingPid = callerApp.pid;
16662            } else {
16663                callerPackage = null;
16664                callingUid = Binder.getCallingUid();
16665                callingPid = Binder.getCallingPid();
16666            }
16667
16668            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16669                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16670
16671            Iterator<String> actions = filter.actionsIterator();
16672            if (actions == null) {
16673                ArrayList<String> noAction = new ArrayList<String>(1);
16674                noAction.add(null);
16675                actions = noAction.iterator();
16676            }
16677
16678            // Collect stickies of users
16679            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16680            while (actions.hasNext()) {
16681                String action = actions.next();
16682                for (int id : userIds) {
16683                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16684                    if (stickies != null) {
16685                        ArrayList<Intent> intents = stickies.get(action);
16686                        if (intents != null) {
16687                            if (stickyIntents == null) {
16688                                stickyIntents = new ArrayList<Intent>();
16689                            }
16690                            stickyIntents.addAll(intents);
16691                        }
16692                    }
16693                }
16694            }
16695        }
16696
16697        ArrayList<Intent> allSticky = null;
16698        if (stickyIntents != null) {
16699            final ContentResolver resolver = mContext.getContentResolver();
16700            // Look for any matching sticky broadcasts...
16701            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16702                Intent intent = stickyIntents.get(i);
16703                // If intent has scheme "content", it will need to acccess
16704                // provider that needs to lock mProviderMap in ActivityThread
16705                // and also it may need to wait application response, so we
16706                // cannot lock ActivityManagerService here.
16707                if (filter.match(resolver, intent, true, TAG) >= 0) {
16708                    if (allSticky == null) {
16709                        allSticky = new ArrayList<Intent>();
16710                    }
16711                    allSticky.add(intent);
16712                }
16713            }
16714        }
16715
16716        // The first sticky in the list is returned directly back to the client.
16717        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16718        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16719        if (receiver == null) {
16720            return sticky;
16721        }
16722
16723        synchronized (this) {
16724            if (callerApp != null && (callerApp.thread == null
16725                    || callerApp.thread.asBinder() != caller.asBinder())) {
16726                // Original caller already died
16727                return null;
16728            }
16729            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16730            if (rl == null) {
16731                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16732                        userId, receiver);
16733                if (rl.app != null) {
16734                    rl.app.receivers.add(rl);
16735                } else {
16736                    try {
16737                        receiver.asBinder().linkToDeath(rl, 0);
16738                    } catch (RemoteException e) {
16739                        return sticky;
16740                    }
16741                    rl.linkedToDeath = true;
16742                }
16743                mRegisteredReceivers.put(receiver.asBinder(), rl);
16744            } else if (rl.uid != callingUid) {
16745                throw new IllegalArgumentException(
16746                        "Receiver requested to register for uid " + callingUid
16747                        + " was previously registered for uid " + rl.uid);
16748            } else if (rl.pid != callingPid) {
16749                throw new IllegalArgumentException(
16750                        "Receiver requested to register for pid " + callingPid
16751                        + " was previously registered for pid " + rl.pid);
16752            } else if (rl.userId != userId) {
16753                throw new IllegalArgumentException(
16754                        "Receiver requested to register for user " + userId
16755                        + " was previously registered for user " + rl.userId);
16756            }
16757            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16758                    permission, callingUid, userId);
16759            rl.add(bf);
16760            if (!bf.debugCheck()) {
16761                Slog.w(TAG, "==> For Dynamic broadcast");
16762            }
16763            mReceiverResolver.addFilter(bf);
16764
16765            // Enqueue broadcasts for all existing stickies that match
16766            // this filter.
16767            if (allSticky != null) {
16768                ArrayList receivers = new ArrayList();
16769                receivers.add(bf);
16770
16771                final int stickyCount = allSticky.size();
16772                for (int i = 0; i < stickyCount; i++) {
16773                    Intent intent = allSticky.get(i);
16774                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16775                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16776                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16777                            null, 0, null, null, false, true, true, -1);
16778                    queue.enqueueParallelBroadcastLocked(r);
16779                    queue.scheduleBroadcastsLocked();
16780                }
16781            }
16782
16783            return sticky;
16784        }
16785    }
16786
16787    public void unregisterReceiver(IIntentReceiver receiver) {
16788        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16789
16790        final long origId = Binder.clearCallingIdentity();
16791        try {
16792            boolean doTrim = false;
16793
16794            synchronized(this) {
16795                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16796                if (rl != null) {
16797                    final BroadcastRecord r = rl.curBroadcast;
16798                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16799                        final boolean doNext = r.queue.finishReceiverLocked(
16800                                r, r.resultCode, r.resultData, r.resultExtras,
16801                                r.resultAbort, false);
16802                        if (doNext) {
16803                            doTrim = true;
16804                            r.queue.processNextBroadcast(false);
16805                        }
16806                    }
16807
16808                    if (rl.app != null) {
16809                        rl.app.receivers.remove(rl);
16810                    }
16811                    removeReceiverLocked(rl);
16812                    if (rl.linkedToDeath) {
16813                        rl.linkedToDeath = false;
16814                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16815                    }
16816                }
16817            }
16818
16819            // If we actually concluded any broadcasts, we might now be able
16820            // to trim the recipients' apps from our working set
16821            if (doTrim) {
16822                trimApplications();
16823                return;
16824            }
16825
16826        } finally {
16827            Binder.restoreCallingIdentity(origId);
16828        }
16829    }
16830
16831    void removeReceiverLocked(ReceiverList rl) {
16832        mRegisteredReceivers.remove(rl.receiver.asBinder());
16833        for (int i = rl.size() - 1; i >= 0; i--) {
16834            mReceiverResolver.removeFilter(rl.get(i));
16835        }
16836    }
16837
16838    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16839        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16840            ProcessRecord r = mLruProcesses.get(i);
16841            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16842                try {
16843                    r.thread.dispatchPackageBroadcast(cmd, packages);
16844                } catch (RemoteException ex) {
16845                }
16846            }
16847        }
16848    }
16849
16850    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16851            int callingUid, int[] users) {
16852        // TODO: come back and remove this assumption to triage all broadcasts
16853        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16854
16855        List<ResolveInfo> receivers = null;
16856        try {
16857            HashSet<ComponentName> singleUserReceivers = null;
16858            boolean scannedFirstReceivers = false;
16859            for (int user : users) {
16860                // Skip users that have Shell restrictions, with exception of always permitted
16861                // Shell broadcasts
16862                if (callingUid == Process.SHELL_UID
16863                        && mUserController.hasUserRestriction(
16864                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16865                        && !isPermittedShellBroadcast(intent)) {
16866                    continue;
16867                }
16868                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16869                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
16870                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16871                    // If this is not the system user, we need to check for
16872                    // any receivers that should be filtered out.
16873                    for (int i=0; i<newReceivers.size(); i++) {
16874                        ResolveInfo ri = newReceivers.get(i);
16875                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16876                            newReceivers.remove(i);
16877                            i--;
16878                        }
16879                    }
16880                }
16881                if (newReceivers != null && newReceivers.size() == 0) {
16882                    newReceivers = null;
16883                }
16884                if (receivers == null) {
16885                    receivers = newReceivers;
16886                } else if (newReceivers != null) {
16887                    // We need to concatenate the additional receivers
16888                    // found with what we have do far.  This would be easy,
16889                    // but we also need to de-dup any receivers that are
16890                    // singleUser.
16891                    if (!scannedFirstReceivers) {
16892                        // Collect any single user receivers we had already retrieved.
16893                        scannedFirstReceivers = true;
16894                        for (int i=0; i<receivers.size(); i++) {
16895                            ResolveInfo ri = receivers.get(i);
16896                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16897                                ComponentName cn = new ComponentName(
16898                                        ri.activityInfo.packageName, ri.activityInfo.name);
16899                                if (singleUserReceivers == null) {
16900                                    singleUserReceivers = new HashSet<ComponentName>();
16901                                }
16902                                singleUserReceivers.add(cn);
16903                            }
16904                        }
16905                    }
16906                    // Add the new results to the existing results, tracking
16907                    // and de-dupping single user receivers.
16908                    for (int i=0; i<newReceivers.size(); i++) {
16909                        ResolveInfo ri = newReceivers.get(i);
16910                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16911                            ComponentName cn = new ComponentName(
16912                                    ri.activityInfo.packageName, ri.activityInfo.name);
16913                            if (singleUserReceivers == null) {
16914                                singleUserReceivers = new HashSet<ComponentName>();
16915                            }
16916                            if (!singleUserReceivers.contains(cn)) {
16917                                singleUserReceivers.add(cn);
16918                                receivers.add(ri);
16919                            }
16920                        } else {
16921                            receivers.add(ri);
16922                        }
16923                    }
16924                }
16925            }
16926        } catch (RemoteException ex) {
16927            // pm is in same process, this will never happen.
16928        }
16929        return receivers;
16930    }
16931
16932    private boolean isPermittedShellBroadcast(Intent intent) {
16933        // remote bugreport should always be allowed to be taken
16934        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
16935    }
16936
16937    final int broadcastIntentLocked(ProcessRecord callerApp,
16938            String callerPackage, Intent intent, String resolvedType,
16939            IIntentReceiver resultTo, int resultCode, String resultData,
16940            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16941            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16942        intent = new Intent(intent);
16943
16944        // By default broadcasts do not go to stopped apps.
16945        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16946
16947        // If we have not finished booting, don't allow this to launch new processes.
16948        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16949            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16950        }
16951
16952        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16953                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16954                + " ordered=" + ordered + " userid=" + userId);
16955        if ((resultTo != null) && !ordered) {
16956            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16957        }
16958
16959        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16960                ALLOW_NON_FULL, "broadcast", callerPackage);
16961
16962        // Make sure that the user who is receiving this broadcast is running.
16963        // If not, we will just skip it. Make an exception for shutdown broadcasts
16964        // and upgrade steps.
16965
16966        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16967            if ((callingUid != Process.SYSTEM_UID
16968                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16969                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16970                Slog.w(TAG, "Skipping broadcast of " + intent
16971                        + ": user " + userId + " is stopped");
16972                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16973            }
16974        }
16975
16976        BroadcastOptions brOptions = null;
16977        if (bOptions != null) {
16978            brOptions = new BroadcastOptions(bOptions);
16979            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16980                // See if the caller is allowed to do this.  Note we are checking against
16981                // the actual real caller (not whoever provided the operation as say a
16982                // PendingIntent), because that who is actually supplied the arguments.
16983                if (checkComponentPermission(
16984                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16985                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16986                        != PackageManager.PERMISSION_GRANTED) {
16987                    String msg = "Permission Denial: " + intent.getAction()
16988                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16989                            + ", uid=" + callingUid + ")"
16990                            + " requires "
16991                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16992                    Slog.w(TAG, msg);
16993                    throw new SecurityException(msg);
16994                }
16995            }
16996        }
16997
16998        // Verify that protected broadcasts are only being sent by system code,
16999        // and that system code is only sending protected broadcasts.
17000        final String action = intent.getAction();
17001        final boolean isProtectedBroadcast;
17002        try {
17003            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17004        } catch (RemoteException e) {
17005            Slog.w(TAG, "Remote exception", e);
17006            return ActivityManager.BROADCAST_SUCCESS;
17007        }
17008
17009        final boolean isCallerSystem;
17010        switch (UserHandle.getAppId(callingUid)) {
17011            case Process.ROOT_UID:
17012            case Process.SYSTEM_UID:
17013            case Process.PHONE_UID:
17014            case Process.BLUETOOTH_UID:
17015            case Process.NFC_UID:
17016                isCallerSystem = true;
17017                break;
17018            default:
17019                isCallerSystem = (callerApp != null) && callerApp.persistent;
17020                break;
17021        }
17022
17023        if (isCallerSystem) {
17024            if (isProtectedBroadcast
17025                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17026                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17027                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17028                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17029                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17030                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17031                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17032                // Broadcast is either protected, or it's a public action that
17033                // we've relaxed, so it's fine for system internals to send.
17034            } else {
17035                // The vast majority of broadcasts sent from system internals
17036                // should be protected to avoid security holes, so yell loudly
17037                // to ensure we examine these cases.
17038                Log.wtf(TAG, "Sending non-protected broadcast " + action
17039                        + " from system", new Throwable());
17040            }
17041
17042        } else {
17043            if (isProtectedBroadcast) {
17044                String msg = "Permission Denial: not allowed to send broadcast "
17045                        + action + " from pid="
17046                        + callingPid + ", uid=" + callingUid;
17047                Slog.w(TAG, msg);
17048                throw new SecurityException(msg);
17049
17050            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17051                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17052                // Special case for compatibility: we don't want apps to send this,
17053                // but historically it has not been protected and apps may be using it
17054                // to poke their own app widget.  So, instead of making it protected,
17055                // just limit it to the caller.
17056                if (callerApp == null) {
17057                    String msg = "Permission Denial: not allowed to send broadcast "
17058                            + action + " from unknown caller.";
17059                    Slog.w(TAG, msg);
17060                    throw new SecurityException(msg);
17061                } else if (intent.getComponent() != null) {
17062                    // They are good enough to send to an explicit component...  verify
17063                    // it is being sent to the calling app.
17064                    if (!intent.getComponent().getPackageName().equals(
17065                            callerApp.info.packageName)) {
17066                        String msg = "Permission Denial: not allowed to send broadcast "
17067                                + action + " to "
17068                                + intent.getComponent().getPackageName() + " from "
17069                                + callerApp.info.packageName;
17070                        Slog.w(TAG, msg);
17071                        throw new SecurityException(msg);
17072                    }
17073                } else {
17074                    // Limit broadcast to their own package.
17075                    intent.setPackage(callerApp.info.packageName);
17076                }
17077            }
17078        }
17079
17080        if (action != null) {
17081            switch (action) {
17082                case Intent.ACTION_UID_REMOVED:
17083                case Intent.ACTION_PACKAGE_REMOVED:
17084                case Intent.ACTION_PACKAGE_CHANGED:
17085                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17086                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17087                case Intent.ACTION_PACKAGES_SUSPENDED:
17088                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17089                    // Handle special intents: if this broadcast is from the package
17090                    // manager about a package being removed, we need to remove all of
17091                    // its activities from the history stack.
17092                    if (checkComponentPermission(
17093                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17094                            callingPid, callingUid, -1, true)
17095                            != PackageManager.PERMISSION_GRANTED) {
17096                        String msg = "Permission Denial: " + intent.getAction()
17097                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17098                                + ", uid=" + callingUid + ")"
17099                                + " requires "
17100                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17101                        Slog.w(TAG, msg);
17102                        throw new SecurityException(msg);
17103                    }
17104                    switch (action) {
17105                        case Intent.ACTION_UID_REMOVED:
17106                            final Bundle intentExtras = intent.getExtras();
17107                            final int uid = intentExtras != null
17108                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17109                            if (uid >= 0) {
17110                                mBatteryStatsService.removeUid(uid);
17111                                mAppOpsService.uidRemoved(uid);
17112                            }
17113                            break;
17114                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17115                            // If resources are unavailable just force stop all those packages
17116                            // and flush the attribute cache as well.
17117                            String list[] =
17118                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17119                            if (list != null && list.length > 0) {
17120                                for (int i = 0; i < list.length; i++) {
17121                                    forceStopPackageLocked(list[i], -1, false, true, true,
17122                                            false, false, userId, "storage unmount");
17123                                }
17124                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17125                                sendPackageBroadcastLocked(
17126                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17127                                        userId);
17128                            }
17129                            break;
17130                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17131                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17132                            break;
17133                        case Intent.ACTION_PACKAGE_REMOVED:
17134                        case Intent.ACTION_PACKAGE_CHANGED:
17135                            Uri data = intent.getData();
17136                            String ssp;
17137                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17138                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17139                                boolean fullUninstall = removed &&
17140                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17141                                final boolean killProcess =
17142                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17143                                if (killProcess) {
17144                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17145                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17146                                            false, true, true, false, fullUninstall, userId,
17147                                            removed ? "pkg removed" : "pkg changed");
17148                                }
17149                                if (removed) {
17150                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17151                                            new String[] {ssp}, userId);
17152                                    if (fullUninstall) {
17153                                        mAppOpsService.packageRemoved(
17154                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17155
17156                                        // Remove all permissions granted from/to this package
17157                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17158
17159                                        removeTasksByPackageNameLocked(ssp, userId);
17160                                        mBatteryStatsService.notePackageUninstalled(ssp);
17161                                    }
17162                                } else {
17163                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17164                                            intent.getStringArrayExtra(
17165                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17166                                }
17167                            }
17168                            break;
17169                        case Intent.ACTION_PACKAGES_SUSPENDED:
17170                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17171                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17172                                    intent.getAction());
17173                            final String[] packageNames = intent.getStringArrayExtra(
17174                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17175                            final int userHandle = intent.getIntExtra(
17176                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17177
17178                            synchronized(ActivityManagerService.this) {
17179                                mRecentTasks.onPackagesSuspendedChanged(
17180                                        packageNames, suspended, userHandle);
17181                            }
17182                            break;
17183                    }
17184                    break;
17185                case Intent.ACTION_PACKAGE_ADDED:
17186                    // Special case for adding a package: by default turn on compatibility mode.
17187                    Uri data = intent.getData();
17188                    String ssp;
17189                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17190                        final boolean replacing =
17191                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17192                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17193
17194                        try {
17195                            ApplicationInfo ai = AppGlobals.getPackageManager().
17196                                    getApplicationInfo(ssp, 0, 0);
17197                            mBatteryStatsService.notePackageInstalled(ssp,
17198                                    ai != null ? ai.versionCode : 0);
17199                        } catch (RemoteException e) {
17200                        }
17201                    }
17202                    break;
17203                case Intent.ACTION_TIMEZONE_CHANGED:
17204                    // If this is the time zone changed action, queue up a message that will reset
17205                    // the timezone of all currently running processes. This message will get
17206                    // queued up before the broadcast happens.
17207                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17208                    break;
17209                case Intent.ACTION_TIME_CHANGED:
17210                    // If the user set the time, let all running processes know.
17211                    final int is24Hour =
17212                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17213                                    : 0;
17214                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17215                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17216                    synchronized (stats) {
17217                        stats.noteCurrentTimeChangedLocked();
17218                    }
17219                    break;
17220                case Intent.ACTION_CLEAR_DNS_CACHE:
17221                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17222                    break;
17223                case Proxy.PROXY_CHANGE_ACTION:
17224                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17225                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17226                    break;
17227                case android.hardware.Camera.ACTION_NEW_PICTURE:
17228                case android.hardware.Camera.ACTION_NEW_VIDEO:
17229                    // These broadcasts are no longer allowed by the system, since they can
17230                    // cause significant thrashing at a crictical point (using the camera).
17231                    // Apps should use JobScehduler to monitor for media provider changes.
17232                    Slog.w(TAG, action + " no longer allowed; dropping from "
17233                            + UserHandle.formatUid(callingUid));
17234                    // Lie; we don't want to crash the app.
17235                    return ActivityManager.BROADCAST_SUCCESS;
17236            }
17237        }
17238
17239        // Add to the sticky list if requested.
17240        if (sticky) {
17241            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17242                    callingPid, callingUid)
17243                    != PackageManager.PERMISSION_GRANTED) {
17244                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17245                        + callingPid + ", uid=" + callingUid
17246                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17247                Slog.w(TAG, msg);
17248                throw new SecurityException(msg);
17249            }
17250            if (requiredPermissions != null && requiredPermissions.length > 0) {
17251                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17252                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17253                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17254            }
17255            if (intent.getComponent() != null) {
17256                throw new SecurityException(
17257                        "Sticky broadcasts can't target a specific component");
17258            }
17259            // We use userId directly here, since the "all" target is maintained
17260            // as a separate set of sticky broadcasts.
17261            if (userId != UserHandle.USER_ALL) {
17262                // But first, if this is not a broadcast to all users, then
17263                // make sure it doesn't conflict with an existing broadcast to
17264                // all users.
17265                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17266                        UserHandle.USER_ALL);
17267                if (stickies != null) {
17268                    ArrayList<Intent> list = stickies.get(intent.getAction());
17269                    if (list != null) {
17270                        int N = list.size();
17271                        int i;
17272                        for (i=0; i<N; i++) {
17273                            if (intent.filterEquals(list.get(i))) {
17274                                throw new IllegalArgumentException(
17275                                        "Sticky broadcast " + intent + " for user "
17276                                        + userId + " conflicts with existing global broadcast");
17277                            }
17278                        }
17279                    }
17280                }
17281            }
17282            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17283            if (stickies == null) {
17284                stickies = new ArrayMap<>();
17285                mStickyBroadcasts.put(userId, stickies);
17286            }
17287            ArrayList<Intent> list = stickies.get(intent.getAction());
17288            if (list == null) {
17289                list = new ArrayList<>();
17290                stickies.put(intent.getAction(), list);
17291            }
17292            final int stickiesCount = list.size();
17293            int i;
17294            for (i = 0; i < stickiesCount; i++) {
17295                if (intent.filterEquals(list.get(i))) {
17296                    // This sticky already exists, replace it.
17297                    list.set(i, new Intent(intent));
17298                    break;
17299                }
17300            }
17301            if (i >= stickiesCount) {
17302                list.add(new Intent(intent));
17303            }
17304        }
17305
17306        int[] users;
17307        if (userId == UserHandle.USER_ALL) {
17308            // Caller wants broadcast to go to all started users.
17309            users = mUserController.getStartedUserArrayLocked();
17310        } else {
17311            // Caller wants broadcast to go to one specific user.
17312            users = new int[] {userId};
17313        }
17314
17315        // Figure out who all will receive this broadcast.
17316        List receivers = null;
17317        List<BroadcastFilter> registeredReceivers = null;
17318        // Need to resolve the intent to interested receivers...
17319        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17320                 == 0) {
17321            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17322        }
17323        if (intent.getComponent() == null) {
17324            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17325                // Query one target user at a time, excluding shell-restricted users
17326                for (int i = 0; i < users.length; i++) {
17327                    if (mUserController.hasUserRestriction(
17328                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17329                        continue;
17330                    }
17331                    List<BroadcastFilter> registeredReceiversForUser =
17332                            mReceiverResolver.queryIntent(intent,
17333                                    resolvedType, false, users[i]);
17334                    if (registeredReceivers == null) {
17335                        registeredReceivers = registeredReceiversForUser;
17336                    } else if (registeredReceiversForUser != null) {
17337                        registeredReceivers.addAll(registeredReceiversForUser);
17338                    }
17339                }
17340            } else {
17341                registeredReceivers = mReceiverResolver.queryIntent(intent,
17342                        resolvedType, false, userId);
17343            }
17344        }
17345
17346        final boolean replacePending =
17347                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17348
17349        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17350                + " replacePending=" + replacePending);
17351
17352        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17353        if (!ordered && NR > 0) {
17354            // If we are not serializing this broadcast, then send the
17355            // registered receivers separately so they don't wait for the
17356            // components to be launched.
17357            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17358            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17359                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17360                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17361                    resultExtras, ordered, sticky, false, userId);
17362            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17363            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17364            if (!replaced) {
17365                queue.enqueueParallelBroadcastLocked(r);
17366                queue.scheduleBroadcastsLocked();
17367            }
17368            registeredReceivers = null;
17369            NR = 0;
17370        }
17371
17372        // Merge into one list.
17373        int ir = 0;
17374        if (receivers != null) {
17375            // A special case for PACKAGE_ADDED: do not allow the package
17376            // being added to see this broadcast.  This prevents them from
17377            // using this as a back door to get run as soon as they are
17378            // installed.  Maybe in the future we want to have a special install
17379            // broadcast or such for apps, but we'd like to deliberately make
17380            // this decision.
17381            String skipPackages[] = null;
17382            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17383                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17384                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17385                Uri data = intent.getData();
17386                if (data != null) {
17387                    String pkgName = data.getSchemeSpecificPart();
17388                    if (pkgName != null) {
17389                        skipPackages = new String[] { pkgName };
17390                    }
17391                }
17392            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17393                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17394            }
17395            if (skipPackages != null && (skipPackages.length > 0)) {
17396                for (String skipPackage : skipPackages) {
17397                    if (skipPackage != null) {
17398                        int NT = receivers.size();
17399                        for (int it=0; it<NT; it++) {
17400                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17401                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17402                                receivers.remove(it);
17403                                it--;
17404                                NT--;
17405                            }
17406                        }
17407                    }
17408                }
17409            }
17410
17411            int NT = receivers != null ? receivers.size() : 0;
17412            int it = 0;
17413            ResolveInfo curt = null;
17414            BroadcastFilter curr = null;
17415            while (it < NT && ir < NR) {
17416                if (curt == null) {
17417                    curt = (ResolveInfo)receivers.get(it);
17418                }
17419                if (curr == null) {
17420                    curr = registeredReceivers.get(ir);
17421                }
17422                if (curr.getPriority() >= curt.priority) {
17423                    // Insert this broadcast record into the final list.
17424                    receivers.add(it, curr);
17425                    ir++;
17426                    curr = null;
17427                    it++;
17428                    NT++;
17429                } else {
17430                    // Skip to the next ResolveInfo in the final list.
17431                    it++;
17432                    curt = null;
17433                }
17434            }
17435        }
17436        while (ir < NR) {
17437            if (receivers == null) {
17438                receivers = new ArrayList();
17439            }
17440            receivers.add(registeredReceivers.get(ir));
17441            ir++;
17442        }
17443
17444        if ((receivers != null && receivers.size() > 0)
17445                || resultTo != null) {
17446            BroadcastQueue queue = broadcastQueueForIntent(intent);
17447            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17448                    callerPackage, callingPid, callingUid, resolvedType,
17449                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17450                    resultData, resultExtras, ordered, sticky, false, userId);
17451
17452            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17453                    + ": prev had " + queue.mOrderedBroadcasts.size());
17454            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17455                    "Enqueueing broadcast " + r.intent.getAction());
17456
17457            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17458            if (!replaced) {
17459                queue.enqueueOrderedBroadcastLocked(r);
17460                queue.scheduleBroadcastsLocked();
17461            }
17462        }
17463
17464        return ActivityManager.BROADCAST_SUCCESS;
17465    }
17466
17467    final Intent verifyBroadcastLocked(Intent intent) {
17468        // Refuse possible leaked file descriptors
17469        if (intent != null && intent.hasFileDescriptors() == true) {
17470            throw new IllegalArgumentException("File descriptors passed in Intent");
17471        }
17472
17473        int flags = intent.getFlags();
17474
17475        if (!mProcessesReady) {
17476            // if the caller really truly claims to know what they're doing, go
17477            // ahead and allow the broadcast without launching any receivers
17478            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17479                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17480            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17481                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17482                        + " before boot completion");
17483                throw new IllegalStateException("Cannot broadcast before boot completed");
17484            }
17485        }
17486
17487        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17488            throw new IllegalArgumentException(
17489                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17490        }
17491
17492        return intent;
17493    }
17494
17495    public final int broadcastIntent(IApplicationThread caller,
17496            Intent intent, String resolvedType, IIntentReceiver resultTo,
17497            int resultCode, String resultData, Bundle resultExtras,
17498            String[] requiredPermissions, int appOp, Bundle bOptions,
17499            boolean serialized, boolean sticky, int userId) {
17500        enforceNotIsolatedCaller("broadcastIntent");
17501        synchronized(this) {
17502            intent = verifyBroadcastLocked(intent);
17503
17504            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17505            final int callingPid = Binder.getCallingPid();
17506            final int callingUid = Binder.getCallingUid();
17507            final long origId = Binder.clearCallingIdentity();
17508            int res = broadcastIntentLocked(callerApp,
17509                    callerApp != null ? callerApp.info.packageName : null,
17510                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17511                    requiredPermissions, appOp, null, serialized, sticky,
17512                    callingPid, callingUid, userId);
17513            Binder.restoreCallingIdentity(origId);
17514            return res;
17515        }
17516    }
17517
17518
17519    int broadcastIntentInPackage(String packageName, int uid,
17520            Intent intent, String resolvedType, IIntentReceiver resultTo,
17521            int resultCode, String resultData, Bundle resultExtras,
17522            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17523            int userId) {
17524        synchronized(this) {
17525            intent = verifyBroadcastLocked(intent);
17526
17527            final long origId = Binder.clearCallingIdentity();
17528            String[] requiredPermissions = requiredPermission == null ? null
17529                    : new String[] {requiredPermission};
17530            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17531                    resultTo, resultCode, resultData, resultExtras,
17532                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17533                    sticky, -1, uid, userId);
17534            Binder.restoreCallingIdentity(origId);
17535            return res;
17536        }
17537    }
17538
17539    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17540        // Refuse possible leaked file descriptors
17541        if (intent != null && intent.hasFileDescriptors() == true) {
17542            throw new IllegalArgumentException("File descriptors passed in Intent");
17543        }
17544
17545        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17546                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17547
17548        synchronized(this) {
17549            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17550                    != PackageManager.PERMISSION_GRANTED) {
17551                String msg = "Permission Denial: unbroadcastIntent() from pid="
17552                        + Binder.getCallingPid()
17553                        + ", uid=" + Binder.getCallingUid()
17554                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17555                Slog.w(TAG, msg);
17556                throw new SecurityException(msg);
17557            }
17558            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17559            if (stickies != null) {
17560                ArrayList<Intent> list = stickies.get(intent.getAction());
17561                if (list != null) {
17562                    int N = list.size();
17563                    int i;
17564                    for (i=0; i<N; i++) {
17565                        if (intent.filterEquals(list.get(i))) {
17566                            list.remove(i);
17567                            break;
17568                        }
17569                    }
17570                    if (list.size() <= 0) {
17571                        stickies.remove(intent.getAction());
17572                    }
17573                }
17574                if (stickies.size() <= 0) {
17575                    mStickyBroadcasts.remove(userId);
17576                }
17577            }
17578        }
17579    }
17580
17581    void backgroundServicesFinishedLocked(int userId) {
17582        for (BroadcastQueue queue : mBroadcastQueues) {
17583            queue.backgroundServicesFinishedLocked(userId);
17584        }
17585    }
17586
17587    public void finishReceiver(IBinder who, int resultCode, String resultData,
17588            Bundle resultExtras, boolean resultAbort, int flags) {
17589        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17590
17591        // Refuse possible leaked file descriptors
17592        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17593            throw new IllegalArgumentException("File descriptors passed in Bundle");
17594        }
17595
17596        final long origId = Binder.clearCallingIdentity();
17597        try {
17598            boolean doNext = false;
17599            BroadcastRecord r;
17600
17601            synchronized(this) {
17602                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17603                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17604                r = queue.getMatchingOrderedReceiver(who);
17605                if (r != null) {
17606                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17607                        resultData, resultExtras, resultAbort, true);
17608                }
17609            }
17610
17611            if (doNext) {
17612                r.queue.processNextBroadcast(false);
17613            }
17614            trimApplications();
17615        } finally {
17616            Binder.restoreCallingIdentity(origId);
17617        }
17618    }
17619
17620    // =========================================================
17621    // INSTRUMENTATION
17622    // =========================================================
17623
17624    public boolean startInstrumentation(ComponentName className,
17625            String profileFile, int flags, Bundle arguments,
17626            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17627            int userId, String abiOverride) {
17628        enforceNotIsolatedCaller("startInstrumentation");
17629        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17630                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17631        // Refuse possible leaked file descriptors
17632        if (arguments != null && arguments.hasFileDescriptors()) {
17633            throw new IllegalArgumentException("File descriptors passed in Bundle");
17634        }
17635
17636        synchronized(this) {
17637            InstrumentationInfo ii = null;
17638            ApplicationInfo ai = null;
17639            try {
17640                ii = mContext.getPackageManager().getInstrumentationInfo(
17641                    className, STOCK_PM_FLAGS);
17642                ai = AppGlobals.getPackageManager().getApplicationInfo(
17643                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17644            } catch (PackageManager.NameNotFoundException e) {
17645            } catch (RemoteException e) {
17646            }
17647            if (ii == null) {
17648                reportStartInstrumentationFailure(watcher, className,
17649                        "Unable to find instrumentation info for: " + className);
17650                return false;
17651            }
17652            if (ai == null) {
17653                reportStartInstrumentationFailure(watcher, className,
17654                        "Unable to find instrumentation target package: " + ii.targetPackage);
17655                return false;
17656            }
17657            if (!ai.hasCode()) {
17658                reportStartInstrumentationFailure(watcher, className,
17659                        "Instrumentation target has no code: " + ii.targetPackage);
17660                return false;
17661            }
17662
17663            int match = mContext.getPackageManager().checkSignatures(
17664                    ii.targetPackage, ii.packageName);
17665            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17666                String msg = "Permission Denial: starting instrumentation "
17667                        + className + " from pid="
17668                        + Binder.getCallingPid()
17669                        + ", uid=" + Binder.getCallingPid()
17670                        + " not allowed because package " + ii.packageName
17671                        + " does not have a signature matching the target "
17672                        + ii.targetPackage;
17673                reportStartInstrumentationFailure(watcher, className, msg);
17674                throw new SecurityException(msg);
17675            }
17676
17677            final long origId = Binder.clearCallingIdentity();
17678            // Instrumentation can kill and relaunch even persistent processes
17679            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17680                    "start instr");
17681            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17682            app.instrumentationClass = className;
17683            app.instrumentationInfo = ai;
17684            app.instrumentationProfileFile = profileFile;
17685            app.instrumentationArguments = arguments;
17686            app.instrumentationWatcher = watcher;
17687            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17688            app.instrumentationResultClass = className;
17689            Binder.restoreCallingIdentity(origId);
17690        }
17691
17692        return true;
17693    }
17694
17695    /**
17696     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17697     * error to the logs, but if somebody is watching, send the report there too.  This enables
17698     * the "am" command to report errors with more information.
17699     *
17700     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17701     * @param cn The component name of the instrumentation.
17702     * @param report The error report.
17703     */
17704    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17705            ComponentName cn, String report) {
17706        Slog.w(TAG, report);
17707        try {
17708            if (watcher != null) {
17709                Bundle results = new Bundle();
17710                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17711                results.putString("Error", report);
17712                watcher.instrumentationStatus(cn, -1, results);
17713            }
17714        } catch (RemoteException e) {
17715            Slog.w(TAG, e);
17716        }
17717    }
17718
17719    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17720        if (app.instrumentationWatcher != null) {
17721            try {
17722                // NOTE:  IInstrumentationWatcher *must* be oneway here
17723                app.instrumentationWatcher.instrumentationFinished(
17724                    app.instrumentationClass,
17725                    resultCode,
17726                    results);
17727            } catch (RemoteException e) {
17728            }
17729        }
17730
17731        // Can't call out of the system process with a lock held, so post a message.
17732        if (app.instrumentationUiAutomationConnection != null) {
17733            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17734                    app.instrumentationUiAutomationConnection).sendToTarget();
17735        }
17736
17737        app.instrumentationWatcher = null;
17738        app.instrumentationUiAutomationConnection = null;
17739        app.instrumentationClass = null;
17740        app.instrumentationInfo = null;
17741        app.instrumentationProfileFile = null;
17742        app.instrumentationArguments = null;
17743
17744        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17745                "finished inst");
17746    }
17747
17748    public void finishInstrumentation(IApplicationThread target,
17749            int resultCode, Bundle results) {
17750        int userId = UserHandle.getCallingUserId();
17751        // Refuse possible leaked file descriptors
17752        if (results != null && results.hasFileDescriptors()) {
17753            throw new IllegalArgumentException("File descriptors passed in Intent");
17754        }
17755
17756        synchronized(this) {
17757            ProcessRecord app = getRecordForAppLocked(target);
17758            if (app == null) {
17759                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17760                return;
17761            }
17762            final long origId = Binder.clearCallingIdentity();
17763            finishInstrumentationLocked(app, resultCode, results);
17764            Binder.restoreCallingIdentity(origId);
17765        }
17766    }
17767
17768    // =========================================================
17769    // CONFIGURATION
17770    // =========================================================
17771
17772    public ConfigurationInfo getDeviceConfigurationInfo() {
17773        ConfigurationInfo config = new ConfigurationInfo();
17774        synchronized (this) {
17775            config.reqTouchScreen = mConfiguration.touchscreen;
17776            config.reqKeyboardType = mConfiguration.keyboard;
17777            config.reqNavigation = mConfiguration.navigation;
17778            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17779                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17780                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17781            }
17782            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17783                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17784                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17785            }
17786            config.reqGlEsVersion = GL_ES_VERSION;
17787        }
17788        return config;
17789    }
17790
17791    ActivityStack getFocusedStack() {
17792        return mStackSupervisor.getFocusedStack();
17793    }
17794
17795    @Override
17796    public int getFocusedStackId() throws RemoteException {
17797        ActivityStack focusedStack = getFocusedStack();
17798        if (focusedStack != null) {
17799            return focusedStack.getStackId();
17800        }
17801        return -1;
17802    }
17803
17804    public Configuration getConfiguration() {
17805        Configuration ci;
17806        synchronized(this) {
17807            ci = new Configuration(mConfiguration);
17808            ci.userSetLocale = false;
17809        }
17810        return ci;
17811    }
17812
17813    @Override
17814    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17815        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17816        synchronized (this) {
17817            mSuppressResizeConfigChanges = suppress;
17818        }
17819    }
17820
17821    @Override
17822    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17823        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17824        if (fromStackId == HOME_STACK_ID) {
17825            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17826        }
17827        synchronized (this) {
17828            final long origId = Binder.clearCallingIdentity();
17829            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17830            if (stack != null) {
17831                mWindowManager.deferSurfaceLayout();
17832                try {
17833                    if (fromStackId == DOCKED_STACK_ID) {
17834
17835                        // We are moving all tasks from the docked stack to the fullscreen stack,
17836                        // which is dismissing the docked stack, so resize all other stacks to
17837                        // fullscreen here already so we don't end up with resize trashing.
17838                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17839                            if (StackId.isResizeableByDockedStack(i)) {
17840                                ActivityStack otherStack = mStackSupervisor.getStack(i);
17841                                if (otherStack != null) {
17842                                    mStackSupervisor.resizeStackLocked(i,
17843                                            null, null, null, PRESERVE_WINDOWS,
17844                                            true /* allowResizeInDockedMode */);
17845                                }
17846                            }
17847                        }
17848                    }
17849                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17850                    final int size = tasks.size();
17851                    if (onTop) {
17852                        for (int i = 0; i < size; i++) {
17853                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17854                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
17855                                    "moveTasksToFullscreenStack", ANIMATE);
17856                        }
17857                    } else {
17858                        for (int i = size - 1; i >= 0; i--) {
17859                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17860                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
17861                        }
17862                    }
17863                } finally {
17864                    mWindowManager.continueSurfaceLayout();
17865                }
17866
17867            }
17868            Binder.restoreCallingIdentity(origId);
17869        }
17870    }
17871
17872    @Override
17873    public void updatePersistentConfiguration(Configuration values) {
17874        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17875                "updateConfiguration()");
17876        enforceWriteSettingsPermission("updateConfiguration()");
17877        if (values == null) {
17878            throw new NullPointerException("Configuration must not be null");
17879        }
17880
17881        int userId = UserHandle.getCallingUserId();
17882
17883        synchronized(this) {
17884            final long origId = Binder.clearCallingIdentity();
17885            updateConfigurationLocked(values, null, false, true, userId);
17886            Binder.restoreCallingIdentity(origId);
17887        }
17888    }
17889
17890    private void updateFontScaleIfNeeded() {
17891        final int currentUserId;
17892        synchronized(this) {
17893            currentUserId = mUserController.getCurrentUserIdLocked();
17894        }
17895        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17896                FONT_SCALE, 1.0f, currentUserId);
17897        if (mConfiguration.fontScale != scaleFactor) {
17898            final Configuration configuration = mWindowManager.computeNewConfiguration();
17899            configuration.fontScale = scaleFactor;
17900            updatePersistentConfiguration(configuration);
17901        }
17902    }
17903
17904    private void enforceWriteSettingsPermission(String func) {
17905        int uid = Binder.getCallingUid();
17906        if (uid == Process.ROOT_UID) {
17907            return;
17908        }
17909
17910        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17911                Settings.getPackageNameForUid(mContext, uid), false)) {
17912            return;
17913        }
17914
17915        String msg = "Permission Denial: " + func + " from pid="
17916                + Binder.getCallingPid()
17917                + ", uid=" + uid
17918                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17919        Slog.w(TAG, msg);
17920        throw new SecurityException(msg);
17921    }
17922
17923    public void updateConfiguration(Configuration values) {
17924        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17925                "updateConfiguration()");
17926
17927        synchronized(this) {
17928            if (values == null && mWindowManager != null) {
17929                // sentinel: fetch the current configuration from the window manager
17930                values = mWindowManager.computeNewConfiguration();
17931            }
17932
17933            if (mWindowManager != null) {
17934                mProcessList.applyDisplaySize(mWindowManager);
17935            }
17936
17937            final long origId = Binder.clearCallingIdentity();
17938            if (values != null) {
17939                Settings.System.clearConfiguration(values);
17940            }
17941            updateConfigurationLocked(values, null, false);
17942            Binder.restoreCallingIdentity(origId);
17943        }
17944    }
17945
17946    void updateUserConfigurationLocked() {
17947        Configuration configuration = new Configuration(mConfiguration);
17948        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17949                mUserController.getCurrentUserIdLocked());
17950        updateConfigurationLocked(configuration, null, false);
17951    }
17952
17953    boolean updateConfigurationLocked(Configuration values,
17954            ActivityRecord starting, boolean initLocale) {
17955        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17956        return updateConfigurationLocked(values, starting, initLocale, false,
17957                UserHandle.USER_NULL);
17958    }
17959
17960    // To cache the list of supported system locales
17961    private String[] mSupportedSystemLocales = null;
17962
17963    /**
17964     * Do either or both things: (1) change the current configuration, and (2)
17965     * make sure the given activity is running with the (now) current
17966     * configuration.  Returns true if the activity has been left running, or
17967     * false if <var>starting</var> is being destroyed to match the new
17968     * configuration.
17969     *
17970     * @param userId is only used when persistent parameter is set to true to persist configuration
17971     *               for that particular user
17972     */
17973    private boolean updateConfigurationLocked(Configuration values,
17974            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17975        int changes = 0;
17976
17977        if (values != null) {
17978            Configuration newConfig = new Configuration(mConfiguration);
17979            changes = newConfig.updateFrom(values);
17980            if (changes != 0) {
17981                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17982                        "Updating configuration to: " + values);
17983
17984                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17985
17986                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17987                    final Locale locale;
17988                    if (values.getLocales().size() == 1) {
17989                        // This is an optimization to avoid the JNI call when the result of
17990                        // getFirstMatch() does not depend on the supported locales.
17991                        locale = values.getLocales().get(0);
17992                    } else {
17993                        if (mSupportedSystemLocales == null) {
17994                            mSupportedSystemLocales =
17995                                    Resources.getSystem().getAssets().getLocales();
17996                        }
17997                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
17998                    }
17999                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18000                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18001                            locale));
18002                }
18003
18004                mConfigurationSeq++;
18005                if (mConfigurationSeq <= 0) {
18006                    mConfigurationSeq = 1;
18007                }
18008                newConfig.seq = mConfigurationSeq;
18009                mConfiguration = newConfig;
18010                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18011                mUsageStatsService.reportConfigurationChange(newConfig,
18012                        mUserController.getCurrentUserIdLocked());
18013                //mUsageStatsService.noteStartConfig(newConfig);
18014
18015                final Configuration configCopy = new Configuration(mConfiguration);
18016
18017                // TODO: If our config changes, should we auto dismiss any currently
18018                // showing dialogs?
18019                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18020
18021                AttributeCache ac = AttributeCache.instance();
18022                if (ac != null) {
18023                    ac.updateConfiguration(configCopy);
18024                }
18025
18026                // Make sure all resources in our process are updated
18027                // right now, so that anyone who is going to retrieve
18028                // resource values after we return will be sure to get
18029                // the new ones.  This is especially important during
18030                // boot, where the first config change needs to guarantee
18031                // all resources have that config before following boot
18032                // code is executed.
18033                mSystemThread.applyConfigurationToResources(configCopy);
18034
18035                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18036                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18037                    msg.obj = new Configuration(configCopy);
18038                    msg.arg1 = userId;
18039                    mHandler.sendMessage(msg);
18040                }
18041
18042                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18043                if (isDensityChange) {
18044                    killAllBackgroundProcesses(Build.VERSION_CODES.N);
18045                }
18046
18047                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18048                    ProcessRecord app = mLruProcesses.get(i);
18049                    try {
18050                        if (app.thread != null) {
18051                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18052                                    + app.processName + " new config " + mConfiguration);
18053                            app.thread.scheduleConfigurationChanged(configCopy);
18054                        }
18055                    } catch (Exception e) {
18056                    }
18057                }
18058                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18059                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18060                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18061                        | Intent.FLAG_RECEIVER_FOREGROUND);
18062                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18063                        null, AppOpsManager.OP_NONE, null, false, false,
18064                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18065                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18066                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18067                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18068                    if (!mProcessesReady) {
18069                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18070                    }
18071                    broadcastIntentLocked(null, null, intent,
18072                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18073                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18074                }
18075            }
18076        }
18077
18078        boolean kept = true;
18079        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18080        // mainStack is null during startup.
18081        if (mainStack != null) {
18082            if (changes != 0 && starting == null) {
18083                // If the configuration changed, and the caller is not already
18084                // in the process of starting an activity, then find the top
18085                // activity to check if its configuration needs to change.
18086                starting = mainStack.topRunningActivityLocked();
18087            }
18088
18089            if (starting != null) {
18090                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18091                // And we need to make sure at this point that all other activities
18092                // are made visible with the correct configuration.
18093                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18094                        !PRESERVE_WINDOWS);
18095            }
18096        }
18097
18098        if (values != null && mWindowManager != null) {
18099            mWindowManager.setNewConfiguration(mConfiguration);
18100        }
18101
18102        return kept;
18103    }
18104
18105    /**
18106     * Decide based on the configuration whether we should shouw the ANR,
18107     * crash, etc dialogs.  The idea is that if there is no affordnace to
18108     * press the on-screen buttons, we shouldn't show the dialog.
18109     *
18110     * A thought: SystemUI might also want to get told about this, the Power
18111     * dialog / global actions also might want different behaviors.
18112     */
18113    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18114        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18115                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18116                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18117        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18118                                    == Configuration.UI_MODE_TYPE_CAR);
18119        return inputMethodExists && uiIsNotCarType && !inVrMode;
18120    }
18121
18122    @Override
18123    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18124        synchronized (this) {
18125            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18126            if (srec != null) {
18127                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18128            }
18129        }
18130        return false;
18131    }
18132
18133    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18134            Intent resultData) {
18135
18136        synchronized (this) {
18137            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18138            if (r != null) {
18139                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18140            }
18141            return false;
18142        }
18143    }
18144
18145    public int getLaunchedFromUid(IBinder activityToken) {
18146        ActivityRecord srec;
18147        synchronized (this) {
18148            srec = ActivityRecord.forTokenLocked(activityToken);
18149        }
18150        if (srec == null) {
18151            return -1;
18152        }
18153        return srec.launchedFromUid;
18154    }
18155
18156    public String getLaunchedFromPackage(IBinder activityToken) {
18157        ActivityRecord srec;
18158        synchronized (this) {
18159            srec = ActivityRecord.forTokenLocked(activityToken);
18160        }
18161        if (srec == null) {
18162            return null;
18163        }
18164        return srec.launchedFromPackage;
18165    }
18166
18167    // =========================================================
18168    // LIFETIME MANAGEMENT
18169    // =========================================================
18170
18171    // Returns which broadcast queue the app is the current [or imminent] receiver
18172    // on, or 'null' if the app is not an active broadcast recipient.
18173    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18174        BroadcastRecord r = app.curReceiver;
18175        if (r != null) {
18176            return r.queue;
18177        }
18178
18179        // It's not the current receiver, but it might be starting up to become one
18180        synchronized (this) {
18181            for (BroadcastQueue queue : mBroadcastQueues) {
18182                r = queue.mPendingBroadcast;
18183                if (r != null && r.curApp == app) {
18184                    // found it; report which queue it's in
18185                    return queue;
18186                }
18187            }
18188        }
18189
18190        return null;
18191    }
18192
18193    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18194            ComponentName targetComponent, String targetProcess) {
18195        if (!mTrackingAssociations) {
18196            return null;
18197        }
18198        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18199                = mAssociations.get(targetUid);
18200        if (components == null) {
18201            components = new ArrayMap<>();
18202            mAssociations.put(targetUid, components);
18203        }
18204        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18205        if (sourceUids == null) {
18206            sourceUids = new SparseArray<>();
18207            components.put(targetComponent, sourceUids);
18208        }
18209        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18210        if (sourceProcesses == null) {
18211            sourceProcesses = new ArrayMap<>();
18212            sourceUids.put(sourceUid, sourceProcesses);
18213        }
18214        Association ass = sourceProcesses.get(sourceProcess);
18215        if (ass == null) {
18216            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18217                    targetProcess);
18218            sourceProcesses.put(sourceProcess, ass);
18219        }
18220        ass.mCount++;
18221        ass.mNesting++;
18222        if (ass.mNesting == 1) {
18223            ass.mStartTime = SystemClock.uptimeMillis();
18224        }
18225        return ass;
18226    }
18227
18228    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18229            ComponentName targetComponent) {
18230        if (!mTrackingAssociations) {
18231            return;
18232        }
18233        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18234                = mAssociations.get(targetUid);
18235        if (components == null) {
18236            return;
18237        }
18238        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18239        if (sourceUids == null) {
18240            return;
18241        }
18242        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18243        if (sourceProcesses == null) {
18244            return;
18245        }
18246        Association ass = sourceProcesses.get(sourceProcess);
18247        if (ass == null || ass.mNesting <= 0) {
18248            return;
18249        }
18250        ass.mNesting--;
18251        if (ass.mNesting == 0) {
18252            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18253        }
18254    }
18255
18256    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18257            boolean doingAll, long now) {
18258        if (mAdjSeq == app.adjSeq) {
18259            // This adjustment has already been computed.
18260            return app.curRawAdj;
18261        }
18262
18263        if (app.thread == null) {
18264            app.adjSeq = mAdjSeq;
18265            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18266            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18267            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18268        }
18269
18270        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18271        app.adjSource = null;
18272        app.adjTarget = null;
18273        app.empty = false;
18274        app.cached = false;
18275
18276        final int activitiesSize = app.activities.size();
18277
18278        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18279            // The max adjustment doesn't allow this app to be anything
18280            // below foreground, so it is not worth doing work for it.
18281            app.adjType = "fixed";
18282            app.adjSeq = mAdjSeq;
18283            app.curRawAdj = app.maxAdj;
18284            app.foregroundActivities = false;
18285            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18286            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18287            // System processes can do UI, and when they do we want to have
18288            // them trim their memory after the user leaves the UI.  To
18289            // facilitate this, here we need to determine whether or not it
18290            // is currently showing UI.
18291            app.systemNoUi = true;
18292            if (app == TOP_APP) {
18293                app.systemNoUi = false;
18294            } else if (activitiesSize > 0) {
18295                for (int j = 0; j < activitiesSize; j++) {
18296                    final ActivityRecord r = app.activities.get(j);
18297                    if (r.visible) {
18298                        app.systemNoUi = false;
18299                    }
18300                }
18301            }
18302            if (!app.systemNoUi) {
18303                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18304            }
18305            return (app.curAdj=app.maxAdj);
18306        }
18307
18308        app.systemNoUi = false;
18309
18310        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18311
18312        // Determine the importance of the process, starting with most
18313        // important to least, and assign an appropriate OOM adjustment.
18314        int adj;
18315        int schedGroup;
18316        int procState;
18317        boolean foregroundActivities = false;
18318        BroadcastQueue queue;
18319        if (app == TOP_APP) {
18320            // The last app on the list is the foreground app.
18321            adj = ProcessList.FOREGROUND_APP_ADJ;
18322            schedGroup = Process.THREAD_GROUP_TOP_APP;
18323            app.adjType = "top-activity";
18324            foregroundActivities = true;
18325            procState = PROCESS_STATE_CUR_TOP;
18326        } else if (app.instrumentationClass != null) {
18327            // Don't want to kill running instrumentation.
18328            adj = ProcessList.FOREGROUND_APP_ADJ;
18329            schedGroup = Process.THREAD_GROUP_DEFAULT;
18330            app.adjType = "instrumentation";
18331            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18332        } else if ((queue = isReceivingBroadcast(app)) != null) {
18333            // An app that is currently receiving a broadcast also
18334            // counts as being in the foreground for OOM killer purposes.
18335            // It's placed in a sched group based on the nature of the
18336            // broadcast as reflected by which queue it's active in.
18337            adj = ProcessList.FOREGROUND_APP_ADJ;
18338            schedGroup = (queue == mFgBroadcastQueue)
18339                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18340            app.adjType = "broadcast";
18341            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18342        } else if (app.executingServices.size() > 0) {
18343            // An app that is currently executing a service callback also
18344            // counts as being in the foreground.
18345            adj = ProcessList.FOREGROUND_APP_ADJ;
18346            schedGroup = app.execServicesFg ?
18347                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18348            app.adjType = "exec-service";
18349            procState = ActivityManager.PROCESS_STATE_SERVICE;
18350            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18351        } else {
18352            // As far as we know the process is empty.  We may change our mind later.
18353            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18354            // At this point we don't actually know the adjustment.  Use the cached adj
18355            // value that the caller wants us to.
18356            adj = cachedAdj;
18357            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18358            app.cached = true;
18359            app.empty = true;
18360            app.adjType = "cch-empty";
18361        }
18362
18363        // Examine all activities if not already foreground.
18364        if (!foregroundActivities && activitiesSize > 0) {
18365            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18366            for (int j = 0; j < activitiesSize; j++) {
18367                final ActivityRecord r = app.activities.get(j);
18368                if (r.app != app) {
18369                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18370                            + app + "?!? Using " + r.app + " instead.");
18371                    continue;
18372                }
18373                if (r.visible) {
18374                    // App has a visible activity; only upgrade adjustment.
18375                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18376                        adj = ProcessList.VISIBLE_APP_ADJ;
18377                        app.adjType = "visible";
18378                    }
18379                    if (procState > PROCESS_STATE_CUR_TOP) {
18380                        procState = PROCESS_STATE_CUR_TOP;
18381                    }
18382                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18383                    app.cached = false;
18384                    app.empty = false;
18385                    foregroundActivities = true;
18386                    if (r.task != null && minLayer > 0) {
18387                        final int layer = r.task.mLayerRank;
18388                        if (layer >= 0 && minLayer > layer) {
18389                            minLayer = layer;
18390                        }
18391                    }
18392                    break;
18393                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18394                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18395                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18396                        app.adjType = "pausing";
18397                    }
18398                    if (procState > PROCESS_STATE_CUR_TOP) {
18399                        procState = PROCESS_STATE_CUR_TOP;
18400                    }
18401                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18402                    app.cached = false;
18403                    app.empty = false;
18404                    foregroundActivities = true;
18405                } else if (r.state == ActivityState.STOPPING) {
18406                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18407                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18408                        app.adjType = "stopping";
18409                    }
18410                    // For the process state, we will at this point consider the
18411                    // process to be cached.  It will be cached either as an activity
18412                    // or empty depending on whether the activity is finishing.  We do
18413                    // this so that we can treat the process as cached for purposes of
18414                    // memory trimming (determing current memory level, trim command to
18415                    // send to process) since there can be an arbitrary number of stopping
18416                    // processes and they should soon all go into the cached state.
18417                    if (!r.finishing) {
18418                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18419                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18420                        }
18421                    }
18422                    app.cached = false;
18423                    app.empty = false;
18424                    foregroundActivities = true;
18425                } else {
18426                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18427                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18428                        app.adjType = "cch-act";
18429                    }
18430                }
18431            }
18432            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18433                adj += minLayer;
18434            }
18435        }
18436
18437        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18438                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18439            if (app.foregroundServices) {
18440                // The user is aware of this app, so make it visible.
18441                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18442                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18443                app.cached = false;
18444                app.adjType = "fg-service";
18445                schedGroup = Process.THREAD_GROUP_DEFAULT;
18446            } else if (app.forcingToForeground != null) {
18447                // The user is aware of this app, so make it visible.
18448                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18449                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18450                app.cached = false;
18451                app.adjType = "force-fg";
18452                app.adjSource = app.forcingToForeground;
18453                schedGroup = Process.THREAD_GROUP_DEFAULT;
18454            }
18455        }
18456
18457        if (app == mHeavyWeightProcess) {
18458            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18459                // We don't want to kill the current heavy-weight process.
18460                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18461                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18462                app.cached = false;
18463                app.adjType = "heavy";
18464            }
18465            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18466                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18467            }
18468        }
18469
18470        if (app == mHomeProcess) {
18471            if (adj > ProcessList.HOME_APP_ADJ) {
18472                // This process is hosting what we currently consider to be the
18473                // home app, so we don't want to let it go into the background.
18474                adj = ProcessList.HOME_APP_ADJ;
18475                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18476                app.cached = false;
18477                app.adjType = "home";
18478            }
18479            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18480                procState = ActivityManager.PROCESS_STATE_HOME;
18481            }
18482        }
18483
18484        if (app == mPreviousProcess && app.activities.size() > 0) {
18485            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18486                // This was the previous process that showed UI to the user.
18487                // We want to try to keep it around more aggressively, to give
18488                // a good experience around switching between two apps.
18489                adj = ProcessList.PREVIOUS_APP_ADJ;
18490                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18491                app.cached = false;
18492                app.adjType = "previous";
18493            }
18494            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18495                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18496            }
18497        }
18498
18499        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18500                + " reason=" + app.adjType);
18501
18502        // By default, we use the computed adjustment.  It may be changed if
18503        // there are applications dependent on our services or providers, but
18504        // this gives us a baseline and makes sure we don't get into an
18505        // infinite recursion.
18506        app.adjSeq = mAdjSeq;
18507        app.curRawAdj = adj;
18508        app.hasStartedServices = false;
18509
18510        if (mBackupTarget != null && app == mBackupTarget.app) {
18511            // If possible we want to avoid killing apps while they're being backed up
18512            if (adj > ProcessList.BACKUP_APP_ADJ) {
18513                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18514                adj = ProcessList.BACKUP_APP_ADJ;
18515                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18516                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18517                }
18518                app.adjType = "backup";
18519                app.cached = false;
18520            }
18521            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18522                procState = ActivityManager.PROCESS_STATE_BACKUP;
18523            }
18524        }
18525
18526        boolean mayBeTop = false;
18527
18528        for (int is = app.services.size()-1;
18529                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18530                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18531                        || procState > ActivityManager.PROCESS_STATE_TOP);
18532                is--) {
18533            ServiceRecord s = app.services.valueAt(is);
18534            if (s.startRequested) {
18535                app.hasStartedServices = true;
18536                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18537                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18538                }
18539                if (app.hasShownUi && app != mHomeProcess) {
18540                    // If this process has shown some UI, let it immediately
18541                    // go to the LRU list because it may be pretty heavy with
18542                    // UI stuff.  We'll tag it with a label just to help
18543                    // debug and understand what is going on.
18544                    if (adj > ProcessList.SERVICE_ADJ) {
18545                        app.adjType = "cch-started-ui-services";
18546                    }
18547                } else {
18548                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18549                        // This service has seen some activity within
18550                        // recent memory, so we will keep its process ahead
18551                        // of the background processes.
18552                        if (adj > ProcessList.SERVICE_ADJ) {
18553                            adj = ProcessList.SERVICE_ADJ;
18554                            app.adjType = "started-services";
18555                            app.cached = false;
18556                        }
18557                    }
18558                    // If we have let the service slide into the background
18559                    // state, still have some text describing what it is doing
18560                    // even though the service no longer has an impact.
18561                    if (adj > ProcessList.SERVICE_ADJ) {
18562                        app.adjType = "cch-started-services";
18563                    }
18564                }
18565            }
18566            for (int conni = s.connections.size()-1;
18567                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18568                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18569                            || procState > ActivityManager.PROCESS_STATE_TOP);
18570                    conni--) {
18571                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18572                for (int i = 0;
18573                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18574                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18575                                || procState > ActivityManager.PROCESS_STATE_TOP);
18576                        i++) {
18577                    // XXX should compute this based on the max of
18578                    // all connected clients.
18579                    ConnectionRecord cr = clist.get(i);
18580                    if (cr.binding.client == app) {
18581                        // Binding to ourself is not interesting.
18582                        continue;
18583                    }
18584                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18585                        ProcessRecord client = cr.binding.client;
18586                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18587                                TOP_APP, doingAll, now);
18588                        int clientProcState = client.curProcState;
18589                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18590                            // If the other app is cached for any reason, for purposes here
18591                            // we are going to consider it empty.  The specific cached state
18592                            // doesn't propagate except under certain conditions.
18593                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18594                        }
18595                        String adjType = null;
18596                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18597                            // Not doing bind OOM management, so treat
18598                            // this guy more like a started service.
18599                            if (app.hasShownUi && app != mHomeProcess) {
18600                                // If this process has shown some UI, let it immediately
18601                                // go to the LRU list because it may be pretty heavy with
18602                                // UI stuff.  We'll tag it with a label just to help
18603                                // debug and understand what is going on.
18604                                if (adj > clientAdj) {
18605                                    adjType = "cch-bound-ui-services";
18606                                }
18607                                app.cached = false;
18608                                clientAdj = adj;
18609                                clientProcState = procState;
18610                            } else {
18611                                if (now >= (s.lastActivity
18612                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18613                                    // This service has not seen activity within
18614                                    // recent memory, so allow it to drop to the
18615                                    // LRU list if there is no other reason to keep
18616                                    // it around.  We'll also tag it with a label just
18617                                    // to help debug and undertand what is going on.
18618                                    if (adj > clientAdj) {
18619                                        adjType = "cch-bound-services";
18620                                    }
18621                                    clientAdj = adj;
18622                                }
18623                            }
18624                        }
18625                        if (adj > clientAdj) {
18626                            // If this process has recently shown UI, and
18627                            // the process that is binding to it is less
18628                            // important than being visible, then we don't
18629                            // care about the binding as much as we care
18630                            // about letting this process get into the LRU
18631                            // list to be killed and restarted if needed for
18632                            // memory.
18633                            if (app.hasShownUi && app != mHomeProcess
18634                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18635                                adjType = "cch-bound-ui-services";
18636                            } else {
18637                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18638                                        |Context.BIND_IMPORTANT)) != 0) {
18639                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18640                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18641                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18642                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18643                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18644                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18645                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18646                                    adj = clientAdj;
18647                                } else {
18648                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18649                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18650                                    }
18651                                }
18652                                if (!client.cached) {
18653                                    app.cached = false;
18654                                }
18655                                adjType = "service";
18656                            }
18657                        }
18658                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18659                            // This will treat important bound services identically to
18660                            // the top app, which may behave differently than generic
18661                            // foreground work.
18662                            if (client.curSchedGroup > schedGroup) {
18663                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18664                                    schedGroup = client.curSchedGroup;
18665                                } else {
18666                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18667                                }
18668                            }
18669                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18670                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18671                                    // Special handling of clients who are in the top state.
18672                                    // We *may* want to consider this process to be in the
18673                                    // top state as well, but only if there is not another
18674                                    // reason for it to be running.  Being on the top is a
18675                                    // special state, meaning you are specifically running
18676                                    // for the current top app.  If the process is already
18677                                    // running in the background for some other reason, it
18678                                    // is more important to continue considering it to be
18679                                    // in the background state.
18680                                    mayBeTop = true;
18681                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18682                                } else {
18683                                    // Special handling for above-top states (persistent
18684                                    // processes).  These should not bring the current process
18685                                    // into the top state, since they are not on top.  Instead
18686                                    // give them the best state after that.
18687                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18688                                        clientProcState =
18689                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18690                                    } else if (mWakefulness
18691                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18692                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18693                                                    != 0) {
18694                                        clientProcState =
18695                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18696                                    } else {
18697                                        clientProcState =
18698                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18699                                    }
18700                                }
18701                            }
18702                        } else {
18703                            if (clientProcState <
18704                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18705                                clientProcState =
18706                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18707                            }
18708                        }
18709                        if (procState > clientProcState) {
18710                            procState = clientProcState;
18711                        }
18712                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18713                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18714                            app.pendingUiClean = true;
18715                        }
18716                        if (adjType != null) {
18717                            app.adjType = adjType;
18718                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18719                                    .REASON_SERVICE_IN_USE;
18720                            app.adjSource = cr.binding.client;
18721                            app.adjSourceProcState = clientProcState;
18722                            app.adjTarget = s.name;
18723                        }
18724                    }
18725                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18726                        app.treatLikeActivity = true;
18727                    }
18728                    final ActivityRecord a = cr.activity;
18729                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18730                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18731                            (a.visible || a.state == ActivityState.RESUMED ||
18732                             a.state == ActivityState.PAUSING)) {
18733                            adj = ProcessList.FOREGROUND_APP_ADJ;
18734                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18735                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18736                                    schedGroup = Process.THREAD_GROUP_TOP_APP;
18737                                } else {
18738                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18739                                }
18740                            }
18741                            app.cached = false;
18742                            app.adjType = "service";
18743                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18744                                    .REASON_SERVICE_IN_USE;
18745                            app.adjSource = a;
18746                            app.adjSourceProcState = procState;
18747                            app.adjTarget = s.name;
18748                        }
18749                    }
18750                }
18751            }
18752        }
18753
18754        for (int provi = app.pubProviders.size()-1;
18755                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18756                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18757                        || procState > ActivityManager.PROCESS_STATE_TOP);
18758                provi--) {
18759            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18760            for (int i = cpr.connections.size()-1;
18761                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18762                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18763                            || procState > ActivityManager.PROCESS_STATE_TOP);
18764                    i--) {
18765                ContentProviderConnection conn = cpr.connections.get(i);
18766                ProcessRecord client = conn.client;
18767                if (client == app) {
18768                    // Being our own client is not interesting.
18769                    continue;
18770                }
18771                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18772                int clientProcState = client.curProcState;
18773                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18774                    // If the other app is cached for any reason, for purposes here
18775                    // we are going to consider it empty.
18776                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18777                }
18778                if (adj > clientAdj) {
18779                    if (app.hasShownUi && app != mHomeProcess
18780                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18781                        app.adjType = "cch-ui-provider";
18782                    } else {
18783                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18784                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18785                        app.adjType = "provider";
18786                    }
18787                    app.cached &= client.cached;
18788                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18789                            .REASON_PROVIDER_IN_USE;
18790                    app.adjSource = client;
18791                    app.adjSourceProcState = clientProcState;
18792                    app.adjTarget = cpr.name;
18793                }
18794                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18795                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18796                        // Special handling of clients who are in the top state.
18797                        // We *may* want to consider this process to be in the
18798                        // top state as well, but only if there is not another
18799                        // reason for it to be running.  Being on the top is a
18800                        // special state, meaning you are specifically running
18801                        // for the current top app.  If the process is already
18802                        // running in the background for some other reason, it
18803                        // is more important to continue considering it to be
18804                        // in the background state.
18805                        mayBeTop = true;
18806                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18807                    } else {
18808                        // Special handling for above-top states (persistent
18809                        // processes).  These should not bring the current process
18810                        // into the top state, since they are not on top.  Instead
18811                        // give them the best state after that.
18812                        clientProcState =
18813                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18814                    }
18815                }
18816                if (procState > clientProcState) {
18817                    procState = clientProcState;
18818                }
18819                if (client.curSchedGroup > schedGroup) {
18820                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18821                }
18822            }
18823            // If the provider has external (non-framework) process
18824            // dependencies, ensure that its adjustment is at least
18825            // FOREGROUND_APP_ADJ.
18826            if (cpr.hasExternalProcessHandles()) {
18827                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18828                    adj = ProcessList.FOREGROUND_APP_ADJ;
18829                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18830                    app.cached = false;
18831                    app.adjType = "provider";
18832                    app.adjTarget = cpr.name;
18833                }
18834                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18835                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18836                }
18837            }
18838        }
18839
18840        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18841            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18842                adj = ProcessList.PREVIOUS_APP_ADJ;
18843                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18844                app.cached = false;
18845                app.adjType = "provider";
18846            }
18847            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18848                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18849            }
18850        }
18851
18852        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18853            // A client of one of our services or providers is in the top state.  We
18854            // *may* want to be in the top state, but not if we are already running in
18855            // the background for some other reason.  For the decision here, we are going
18856            // to pick out a few specific states that we want to remain in when a client
18857            // is top (states that tend to be longer-term) and otherwise allow it to go
18858            // to the top state.
18859            switch (procState) {
18860                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18861                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18862                case ActivityManager.PROCESS_STATE_SERVICE:
18863                    // These all are longer-term states, so pull them up to the top
18864                    // of the background states, but not all the way to the top state.
18865                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18866                    break;
18867                default:
18868                    // Otherwise, top is a better choice, so take it.
18869                    procState = ActivityManager.PROCESS_STATE_TOP;
18870                    break;
18871            }
18872        }
18873
18874        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18875            if (app.hasClientActivities) {
18876                // This is a cached process, but with client activities.  Mark it so.
18877                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18878                app.adjType = "cch-client-act";
18879            } else if (app.treatLikeActivity) {
18880                // This is a cached process, but somebody wants us to treat it like it has
18881                // an activity, okay!
18882                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18883                app.adjType = "cch-as-act";
18884            }
18885        }
18886
18887        if (adj == ProcessList.SERVICE_ADJ) {
18888            if (doingAll) {
18889                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18890                mNewNumServiceProcs++;
18891                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18892                if (!app.serviceb) {
18893                    // This service isn't far enough down on the LRU list to
18894                    // normally be a B service, but if we are low on RAM and it
18895                    // is large we want to force it down since we would prefer to
18896                    // keep launcher over it.
18897                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18898                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18899                        app.serviceHighRam = true;
18900                        app.serviceb = true;
18901                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18902                    } else {
18903                        mNewNumAServiceProcs++;
18904                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18905                    }
18906                } else {
18907                    app.serviceHighRam = false;
18908                }
18909            }
18910            if (app.serviceb) {
18911                adj = ProcessList.SERVICE_B_ADJ;
18912            }
18913        }
18914
18915        app.curRawAdj = adj;
18916
18917        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18918        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18919        if (adj > app.maxAdj) {
18920            adj = app.maxAdj;
18921            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18922                schedGroup = Process.THREAD_GROUP_DEFAULT;
18923            }
18924        }
18925
18926        // Do final modification to adj.  Everything we do between here and applying
18927        // the final setAdj must be done in this function, because we will also use
18928        // it when computing the final cached adj later.  Note that we don't need to
18929        // worry about this for max adj above, since max adj will always be used to
18930        // keep it out of the cached vaues.
18931        app.curAdj = app.modifyRawOomAdj(adj);
18932        app.curSchedGroup = schedGroup;
18933        app.curProcState = procState;
18934        app.foregroundActivities = foregroundActivities;
18935
18936        return app.curRawAdj;
18937    }
18938
18939    /**
18940     * Record new PSS sample for a process.
18941     */
18942    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
18943            long now) {
18944        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
18945                swapPss * 1024);
18946        proc.lastPssTime = now;
18947        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18948        if (DEBUG_PSS) Slog.d(TAG_PSS,
18949                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18950                + " state=" + ProcessList.makeProcStateString(procState));
18951        if (proc.initialIdlePss == 0) {
18952            proc.initialIdlePss = pss;
18953        }
18954        proc.lastPss = pss;
18955        proc.lastSwapPss = swapPss;
18956        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18957            proc.lastCachedPss = pss;
18958            proc.lastCachedSwapPss = swapPss;
18959        }
18960
18961        final SparseArray<Pair<Long, String>> watchUids
18962                = mMemWatchProcesses.getMap().get(proc.processName);
18963        Long check = null;
18964        if (watchUids != null) {
18965            Pair<Long, String> val = watchUids.get(proc.uid);
18966            if (val == null) {
18967                val = watchUids.get(0);
18968            }
18969            if (val != null) {
18970                check = val.first;
18971            }
18972        }
18973        if (check != null) {
18974            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18975                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18976                if (!isDebuggable) {
18977                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18978                        isDebuggable = true;
18979                    }
18980                }
18981                if (isDebuggable) {
18982                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18983                    final ProcessRecord myProc = proc;
18984                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18985                    mMemWatchDumpProcName = proc.processName;
18986                    mMemWatchDumpFile = heapdumpFile.toString();
18987                    mMemWatchDumpPid = proc.pid;
18988                    mMemWatchDumpUid = proc.uid;
18989                    BackgroundThread.getHandler().post(new Runnable() {
18990                        @Override
18991                        public void run() {
18992                            revokeUriPermission(ActivityThread.currentActivityThread()
18993                                            .getApplicationThread(),
18994                                    DumpHeapActivity.JAVA_URI,
18995                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18996                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18997                                    UserHandle.myUserId());
18998                            ParcelFileDescriptor fd = null;
18999                            try {
19000                                heapdumpFile.delete();
19001                                fd = ParcelFileDescriptor.open(heapdumpFile,
19002                                        ParcelFileDescriptor.MODE_CREATE |
19003                                                ParcelFileDescriptor.MODE_TRUNCATE |
19004                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19005                                                ParcelFileDescriptor.MODE_APPEND);
19006                                IApplicationThread thread = myProc.thread;
19007                                if (thread != null) {
19008                                    try {
19009                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19010                                                "Requesting dump heap from "
19011                                                + myProc + " to " + heapdumpFile);
19012                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19013                                    } catch (RemoteException e) {
19014                                    }
19015                                }
19016                            } catch (FileNotFoundException e) {
19017                                e.printStackTrace();
19018                            } finally {
19019                                if (fd != null) {
19020                                    try {
19021                                        fd.close();
19022                                    } catch (IOException e) {
19023                                    }
19024                                }
19025                            }
19026                        }
19027                    });
19028                } else {
19029                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19030                            + ", but debugging not enabled");
19031                }
19032            }
19033        }
19034    }
19035
19036    /**
19037     * Schedule PSS collection of a process.
19038     */
19039    void requestPssLocked(ProcessRecord proc, int procState) {
19040        if (mPendingPssProcesses.contains(proc)) {
19041            return;
19042        }
19043        if (mPendingPssProcesses.size() == 0) {
19044            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19045        }
19046        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19047        proc.pssProcState = procState;
19048        mPendingPssProcesses.add(proc);
19049    }
19050
19051    /**
19052     * Schedule PSS collection of all processes.
19053     */
19054    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19055        if (!always) {
19056            if (now < (mLastFullPssTime +
19057                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19058                return;
19059            }
19060        }
19061        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19062        mLastFullPssTime = now;
19063        mFullPssPending = true;
19064        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19065        mPendingPssProcesses.clear();
19066        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19067            ProcessRecord app = mLruProcesses.get(i);
19068            if (app.thread == null
19069                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19070                continue;
19071            }
19072            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19073                app.pssProcState = app.setProcState;
19074                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19075                        mTestPssMode, isSleeping(), now);
19076                mPendingPssProcesses.add(app);
19077            }
19078        }
19079        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19080    }
19081
19082    public void setTestPssMode(boolean enabled) {
19083        synchronized (this) {
19084            mTestPssMode = enabled;
19085            if (enabled) {
19086                // Whenever we enable the mode, we want to take a snapshot all of current
19087                // process mem use.
19088                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19089            }
19090        }
19091    }
19092
19093    /**
19094     * Ask a given process to GC right now.
19095     */
19096    final void performAppGcLocked(ProcessRecord app) {
19097        try {
19098            app.lastRequestedGc = SystemClock.uptimeMillis();
19099            if (app.thread != null) {
19100                if (app.reportLowMemory) {
19101                    app.reportLowMemory = false;
19102                    app.thread.scheduleLowMemory();
19103                } else {
19104                    app.thread.processInBackground();
19105                }
19106            }
19107        } catch (Exception e) {
19108            // whatever.
19109        }
19110    }
19111
19112    /**
19113     * Returns true if things are idle enough to perform GCs.
19114     */
19115    private final boolean canGcNowLocked() {
19116        boolean processingBroadcasts = false;
19117        for (BroadcastQueue q : mBroadcastQueues) {
19118            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19119                processingBroadcasts = true;
19120            }
19121        }
19122        return !processingBroadcasts
19123                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19124    }
19125
19126    /**
19127     * Perform GCs on all processes that are waiting for it, but only
19128     * if things are idle.
19129     */
19130    final void performAppGcsLocked() {
19131        final int N = mProcessesToGc.size();
19132        if (N <= 0) {
19133            return;
19134        }
19135        if (canGcNowLocked()) {
19136            while (mProcessesToGc.size() > 0) {
19137                ProcessRecord proc = mProcessesToGc.remove(0);
19138                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19139                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19140                            <= SystemClock.uptimeMillis()) {
19141                        // To avoid spamming the system, we will GC processes one
19142                        // at a time, waiting a few seconds between each.
19143                        performAppGcLocked(proc);
19144                        scheduleAppGcsLocked();
19145                        return;
19146                    } else {
19147                        // It hasn't been long enough since we last GCed this
19148                        // process...  put it in the list to wait for its time.
19149                        addProcessToGcListLocked(proc);
19150                        break;
19151                    }
19152                }
19153            }
19154
19155            scheduleAppGcsLocked();
19156        }
19157    }
19158
19159    /**
19160     * If all looks good, perform GCs on all processes waiting for them.
19161     */
19162    final void performAppGcsIfAppropriateLocked() {
19163        if (canGcNowLocked()) {
19164            performAppGcsLocked();
19165            return;
19166        }
19167        // Still not idle, wait some more.
19168        scheduleAppGcsLocked();
19169    }
19170
19171    /**
19172     * Schedule the execution of all pending app GCs.
19173     */
19174    final void scheduleAppGcsLocked() {
19175        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19176
19177        if (mProcessesToGc.size() > 0) {
19178            // Schedule a GC for the time to the next process.
19179            ProcessRecord proc = mProcessesToGc.get(0);
19180            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19181
19182            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19183            long now = SystemClock.uptimeMillis();
19184            if (when < (now+GC_TIMEOUT)) {
19185                when = now + GC_TIMEOUT;
19186            }
19187            mHandler.sendMessageAtTime(msg, when);
19188        }
19189    }
19190
19191    /**
19192     * Add a process to the array of processes waiting to be GCed.  Keeps the
19193     * list in sorted order by the last GC time.  The process can't already be
19194     * on the list.
19195     */
19196    final void addProcessToGcListLocked(ProcessRecord proc) {
19197        boolean added = false;
19198        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19199            if (mProcessesToGc.get(i).lastRequestedGc <
19200                    proc.lastRequestedGc) {
19201                added = true;
19202                mProcessesToGc.add(i+1, proc);
19203                break;
19204            }
19205        }
19206        if (!added) {
19207            mProcessesToGc.add(0, proc);
19208        }
19209    }
19210
19211    /**
19212     * Set up to ask a process to GC itself.  This will either do it
19213     * immediately, or put it on the list of processes to gc the next
19214     * time things are idle.
19215     */
19216    final void scheduleAppGcLocked(ProcessRecord app) {
19217        long now = SystemClock.uptimeMillis();
19218        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19219            return;
19220        }
19221        if (!mProcessesToGc.contains(app)) {
19222            addProcessToGcListLocked(app);
19223            scheduleAppGcsLocked();
19224        }
19225    }
19226
19227    final void checkExcessivePowerUsageLocked(boolean doKills) {
19228        updateCpuStatsNow();
19229
19230        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19231        boolean doWakeKills = doKills;
19232        boolean doCpuKills = doKills;
19233        if (mLastPowerCheckRealtime == 0) {
19234            doWakeKills = false;
19235        }
19236        if (mLastPowerCheckUptime == 0) {
19237            doCpuKills = false;
19238        }
19239        if (stats.isScreenOn()) {
19240            doWakeKills = false;
19241        }
19242        final long curRealtime = SystemClock.elapsedRealtime();
19243        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19244        final long curUptime = SystemClock.uptimeMillis();
19245        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19246        mLastPowerCheckRealtime = curRealtime;
19247        mLastPowerCheckUptime = curUptime;
19248        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19249            doWakeKills = false;
19250        }
19251        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19252            doCpuKills = false;
19253        }
19254        int i = mLruProcesses.size();
19255        while (i > 0) {
19256            i--;
19257            ProcessRecord app = mLruProcesses.get(i);
19258            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19259                long wtime;
19260                synchronized (stats) {
19261                    wtime = stats.getProcessWakeTime(app.info.uid,
19262                            app.pid, curRealtime);
19263                }
19264                long wtimeUsed = wtime - app.lastWakeTime;
19265                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19266                if (DEBUG_POWER) {
19267                    StringBuilder sb = new StringBuilder(128);
19268                    sb.append("Wake for ");
19269                    app.toShortString(sb);
19270                    sb.append(": over ");
19271                    TimeUtils.formatDuration(realtimeSince, sb);
19272                    sb.append(" used ");
19273                    TimeUtils.formatDuration(wtimeUsed, sb);
19274                    sb.append(" (");
19275                    sb.append((wtimeUsed*100)/realtimeSince);
19276                    sb.append("%)");
19277                    Slog.i(TAG_POWER, sb.toString());
19278                    sb.setLength(0);
19279                    sb.append("CPU for ");
19280                    app.toShortString(sb);
19281                    sb.append(": over ");
19282                    TimeUtils.formatDuration(uptimeSince, sb);
19283                    sb.append(" used ");
19284                    TimeUtils.formatDuration(cputimeUsed, sb);
19285                    sb.append(" (");
19286                    sb.append((cputimeUsed*100)/uptimeSince);
19287                    sb.append("%)");
19288                    Slog.i(TAG_POWER, sb.toString());
19289                }
19290                // If a process has held a wake lock for more
19291                // than 50% of the time during this period,
19292                // that sounds bad.  Kill!
19293                if (doWakeKills && realtimeSince > 0
19294                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19295                    synchronized (stats) {
19296                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19297                                realtimeSince, wtimeUsed);
19298                    }
19299                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19300                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19301                } else if (doCpuKills && uptimeSince > 0
19302                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19303                    synchronized (stats) {
19304                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19305                                uptimeSince, cputimeUsed);
19306                    }
19307                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19308                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19309                } else {
19310                    app.lastWakeTime = wtime;
19311                    app.lastCpuTime = app.curCpuTime;
19312                }
19313            }
19314        }
19315    }
19316
19317    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19318            long nowElapsed) {
19319        boolean success = true;
19320
19321        if (app.curRawAdj != app.setRawAdj) {
19322            app.setRawAdj = app.curRawAdj;
19323        }
19324
19325        int changes = 0;
19326
19327        if (app.curAdj != app.setAdj) {
19328            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19329            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19330                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19331                    + app.adjType);
19332            app.setAdj = app.curAdj;
19333        }
19334
19335        if (app.setSchedGroup != app.curSchedGroup) {
19336            app.setSchedGroup = app.curSchedGroup;
19337            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19338                    "Setting process group of " + app.processName
19339                    + " to " + app.curSchedGroup);
19340            if (app.waitingToKill != null && app.curReceiver == null
19341                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19342                app.kill(app.waitingToKill, true);
19343                success = false;
19344            } else {
19345                if (true) {
19346                    long oldId = Binder.clearCallingIdentity();
19347                    try {
19348                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19349                    } catch (Exception e) {
19350                        Slog.w(TAG, "Failed setting process group of " + app.pid
19351                                + " to " + app.curSchedGroup);
19352                        e.printStackTrace();
19353                    } finally {
19354                        Binder.restoreCallingIdentity(oldId);
19355                    }
19356                } else {
19357                    if (app.thread != null) {
19358                        try {
19359                            app.thread.setSchedulingGroup(app.curSchedGroup);
19360                        } catch (RemoteException e) {
19361                        }
19362                    }
19363                }
19364            }
19365        }
19366        if (app.repForegroundActivities != app.foregroundActivities) {
19367            app.repForegroundActivities = app.foregroundActivities;
19368            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19369        }
19370        if (app.repProcState != app.curProcState) {
19371            app.repProcState = app.curProcState;
19372            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19373            if (app.thread != null) {
19374                try {
19375                    if (false) {
19376                        //RuntimeException h = new RuntimeException("here");
19377                        Slog.i(TAG, "Sending new process state " + app.repProcState
19378                                + " to " + app /*, h*/);
19379                    }
19380                    app.thread.setProcessState(app.repProcState);
19381                } catch (RemoteException e) {
19382                }
19383            }
19384        }
19385        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19386                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19387            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19388                // Experimental code to more aggressively collect pss while
19389                // running test...  the problem is that this tends to collect
19390                // the data right when a process is transitioning between process
19391                // states, which well tend to give noisy data.
19392                long start = SystemClock.uptimeMillis();
19393                long pss = Debug.getPss(app.pid, mTmpLong, null);
19394                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19395                mPendingPssProcesses.remove(app);
19396                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19397                        + " to " + app.curProcState + ": "
19398                        + (SystemClock.uptimeMillis()-start) + "ms");
19399            }
19400            app.lastStateTime = now;
19401            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19402                    mTestPssMode, isSleeping(), now);
19403            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19404                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19405                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19406                    + (app.nextPssTime-now) + ": " + app);
19407        } else {
19408            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19409                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19410                    mTestPssMode)))) {
19411                requestPssLocked(app, app.setProcState);
19412                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19413                        mTestPssMode, isSleeping(), now);
19414            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19415                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19416        }
19417        if (app.setProcState != app.curProcState) {
19418            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19419                    "Proc state change of " + app.processName
19420                            + " to " + app.curProcState);
19421            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19422            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19423            if (setImportant && !curImportant) {
19424                // This app is no longer something we consider important enough to allow to
19425                // use arbitrary amounts of battery power.  Note
19426                // its current wake lock time to later know to kill it if
19427                // it is not behaving well.
19428                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19429                synchronized (stats) {
19430                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19431                            app.pid, nowElapsed);
19432                }
19433                app.lastCpuTime = app.curCpuTime;
19434
19435            }
19436            // Inform UsageStats of important process state change
19437            // Must be called before updating setProcState
19438            maybeUpdateUsageStatsLocked(app, nowElapsed);
19439
19440            app.setProcState = app.curProcState;
19441            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19442                app.notCachedSinceIdle = false;
19443            }
19444            if (!doingAll) {
19445                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19446            } else {
19447                app.procStateChanged = true;
19448            }
19449        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19450                > USAGE_STATS_INTERACTION_INTERVAL) {
19451            // For apps that sit around for a long time in the interactive state, we need
19452            // to report this at least once a day so they don't go idle.
19453            maybeUpdateUsageStatsLocked(app, nowElapsed);
19454        }
19455
19456        if (changes != 0) {
19457            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19458                    "Changes in " + app + ": " + changes);
19459            int i = mPendingProcessChanges.size()-1;
19460            ProcessChangeItem item = null;
19461            while (i >= 0) {
19462                item = mPendingProcessChanges.get(i);
19463                if (item.pid == app.pid) {
19464                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19465                            "Re-using existing item: " + item);
19466                    break;
19467                }
19468                i--;
19469            }
19470            if (i < 0) {
19471                // No existing item in pending changes; need a new one.
19472                final int NA = mAvailProcessChanges.size();
19473                if (NA > 0) {
19474                    item = mAvailProcessChanges.remove(NA-1);
19475                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19476                            "Retrieving available item: " + item);
19477                } else {
19478                    item = new ProcessChangeItem();
19479                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19480                            "Allocating new item: " + item);
19481                }
19482                item.changes = 0;
19483                item.pid = app.pid;
19484                item.uid = app.info.uid;
19485                if (mPendingProcessChanges.size() == 0) {
19486                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19487                            "*** Enqueueing dispatch processes changed!");
19488                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19489                }
19490                mPendingProcessChanges.add(item);
19491            }
19492            item.changes |= changes;
19493            item.processState = app.repProcState;
19494            item.foregroundActivities = app.repForegroundActivities;
19495            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19496                    "Item " + Integer.toHexString(System.identityHashCode(item))
19497                    + " " + app.toShortString() + ": changes=" + item.changes
19498                    + " procState=" + item.processState
19499                    + " foreground=" + item.foregroundActivities
19500                    + " type=" + app.adjType + " source=" + app.adjSource
19501                    + " target=" + app.adjTarget);
19502        }
19503
19504        return success;
19505    }
19506
19507    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19508        final UidRecord.ChangeItem pendingChange;
19509        if (uidRec == null || uidRec.pendingChange == null) {
19510            if (mPendingUidChanges.size() == 0) {
19511                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19512                        "*** Enqueueing dispatch uid changed!");
19513                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19514            }
19515            final int NA = mAvailUidChanges.size();
19516            if (NA > 0) {
19517                pendingChange = mAvailUidChanges.remove(NA-1);
19518                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19519                        "Retrieving available item: " + pendingChange);
19520            } else {
19521                pendingChange = new UidRecord.ChangeItem();
19522                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19523                        "Allocating new item: " + pendingChange);
19524            }
19525            if (uidRec != null) {
19526                uidRec.pendingChange = pendingChange;
19527                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19528                    // If this uid is going away, and we haven't yet reported it is gone,
19529                    // then do so now.
19530                    change = UidRecord.CHANGE_GONE_IDLE;
19531                }
19532            } else if (uid < 0) {
19533                throw new IllegalArgumentException("No UidRecord or uid");
19534            }
19535            pendingChange.uidRecord = uidRec;
19536            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19537            mPendingUidChanges.add(pendingChange);
19538        } else {
19539            pendingChange = uidRec.pendingChange;
19540            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19541                change = UidRecord.CHANGE_GONE_IDLE;
19542            }
19543        }
19544        pendingChange.change = change;
19545        pendingChange.processState = uidRec != null
19546                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19547    }
19548
19549    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19550            String authority) {
19551        if (app == null) return;
19552        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19553            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19554            if (userState == null) return;
19555            final long now = SystemClock.elapsedRealtime();
19556            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19557            if (lastReported == null || lastReported < now - 60 * 1000L) {
19558                mUsageStatsService.reportContentProviderUsage(
19559                        authority, providerPkgName, app.userId);
19560                userState.mProviderLastReportedFg.put(authority, now);
19561            }
19562        }
19563    }
19564
19565    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19566        if (DEBUG_USAGE_STATS) {
19567            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19568                    + "] state changes: old = " + app.setProcState + ", new = "
19569                    + app.curProcState);
19570        }
19571        if (mUsageStatsService == null) {
19572            return;
19573        }
19574        boolean isInteraction;
19575        // To avoid some abuse patterns, we are going to be careful about what we consider
19576        // to be an app interaction.  Being the top activity doesn't count while the display
19577        // is sleeping, nor do short foreground services.
19578        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19579            isInteraction = true;
19580            app.fgInteractionTime = 0;
19581        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19582            if (app.fgInteractionTime == 0) {
19583                app.fgInteractionTime = nowElapsed;
19584                isInteraction = false;
19585            } else {
19586                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19587            }
19588        } else {
19589            isInteraction = app.curProcState
19590                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19591            app.fgInteractionTime = 0;
19592        }
19593        if (isInteraction && (!app.reportedInteraction
19594                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19595            app.interactionEventTime = nowElapsed;
19596            String[] packages = app.getPackageList();
19597            if (packages != null) {
19598                for (int i = 0; i < packages.length; i++) {
19599                    mUsageStatsService.reportEvent(packages[i], app.userId,
19600                            UsageEvents.Event.SYSTEM_INTERACTION);
19601                }
19602            }
19603        }
19604        app.reportedInteraction = isInteraction;
19605        if (!isInteraction) {
19606            app.interactionEventTime = 0;
19607        }
19608    }
19609
19610    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19611        if (proc.thread != null) {
19612            if (proc.baseProcessTracker != null) {
19613                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19614            }
19615        }
19616    }
19617
19618    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19619            ProcessRecord TOP_APP, boolean doingAll, long now) {
19620        if (app.thread == null) {
19621            return false;
19622        }
19623
19624        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19625
19626        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19627    }
19628
19629    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19630            boolean oomAdj) {
19631        if (isForeground != proc.foregroundServices) {
19632            proc.foregroundServices = isForeground;
19633            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19634                    proc.info.uid);
19635            if (isForeground) {
19636                if (curProcs == null) {
19637                    curProcs = new ArrayList<ProcessRecord>();
19638                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19639                }
19640                if (!curProcs.contains(proc)) {
19641                    curProcs.add(proc);
19642                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19643                            proc.info.packageName, proc.info.uid);
19644                }
19645            } else {
19646                if (curProcs != null) {
19647                    if (curProcs.remove(proc)) {
19648                        mBatteryStatsService.noteEvent(
19649                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19650                                proc.info.packageName, proc.info.uid);
19651                        if (curProcs.size() <= 0) {
19652                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19653                        }
19654                    }
19655                }
19656            }
19657            if (oomAdj) {
19658                updateOomAdjLocked();
19659            }
19660        }
19661    }
19662
19663    private final ActivityRecord resumedAppLocked() {
19664        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19665        String pkg;
19666        int uid;
19667        if (act != null) {
19668            pkg = act.packageName;
19669            uid = act.info.applicationInfo.uid;
19670        } else {
19671            pkg = null;
19672            uid = -1;
19673        }
19674        // Has the UID or resumed package name changed?
19675        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19676                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19677            if (mCurResumedPackage != null) {
19678                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19679                        mCurResumedPackage, mCurResumedUid);
19680            }
19681            mCurResumedPackage = pkg;
19682            mCurResumedUid = uid;
19683            if (mCurResumedPackage != null) {
19684                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19685                        mCurResumedPackage, mCurResumedUid);
19686            }
19687        }
19688        return act;
19689    }
19690
19691    final boolean updateOomAdjLocked(ProcessRecord app) {
19692        final ActivityRecord TOP_ACT = resumedAppLocked();
19693        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19694        final boolean wasCached = app.cached;
19695
19696        mAdjSeq++;
19697
19698        // This is the desired cached adjusment we want to tell it to use.
19699        // If our app is currently cached, we know it, and that is it.  Otherwise,
19700        // we don't know it yet, and it needs to now be cached we will then
19701        // need to do a complete oom adj.
19702        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19703                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19704        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19705                SystemClock.uptimeMillis());
19706        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19707            // Changed to/from cached state, so apps after it in the LRU
19708            // list may also be changed.
19709            updateOomAdjLocked();
19710        }
19711        return success;
19712    }
19713
19714    final void updateOomAdjLocked() {
19715        final ActivityRecord TOP_ACT = resumedAppLocked();
19716        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19717        final long now = SystemClock.uptimeMillis();
19718        final long nowElapsed = SystemClock.elapsedRealtime();
19719        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19720        final int N = mLruProcesses.size();
19721
19722        if (false) {
19723            RuntimeException e = new RuntimeException();
19724            e.fillInStackTrace();
19725            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19726        }
19727
19728        // Reset state in all uid records.
19729        for (int i=mActiveUids.size()-1; i>=0; i--) {
19730            final UidRecord uidRec = mActiveUids.valueAt(i);
19731            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19732                    "Starting update of " + uidRec);
19733            uidRec.reset();
19734        }
19735
19736        mStackSupervisor.rankTaskLayersIfNeeded();
19737
19738        mAdjSeq++;
19739        mNewNumServiceProcs = 0;
19740        mNewNumAServiceProcs = 0;
19741
19742        final int emptyProcessLimit;
19743        final int cachedProcessLimit;
19744        if (mProcessLimit <= 0) {
19745            emptyProcessLimit = cachedProcessLimit = 0;
19746        } else if (mProcessLimit == 1) {
19747            emptyProcessLimit = 1;
19748            cachedProcessLimit = 0;
19749        } else {
19750            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19751            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19752        }
19753
19754        // Let's determine how many processes we have running vs.
19755        // how many slots we have for background processes; we may want
19756        // to put multiple processes in a slot of there are enough of
19757        // them.
19758        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19759                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19760        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19761        if (numEmptyProcs > cachedProcessLimit) {
19762            // If there are more empty processes than our limit on cached
19763            // processes, then use the cached process limit for the factor.
19764            // This ensures that the really old empty processes get pushed
19765            // down to the bottom, so if we are running low on memory we will
19766            // have a better chance at keeping around more cached processes
19767            // instead of a gazillion empty processes.
19768            numEmptyProcs = cachedProcessLimit;
19769        }
19770        int emptyFactor = numEmptyProcs/numSlots;
19771        if (emptyFactor < 1) emptyFactor = 1;
19772        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19773        if (cachedFactor < 1) cachedFactor = 1;
19774        int stepCached = 0;
19775        int stepEmpty = 0;
19776        int numCached = 0;
19777        int numEmpty = 0;
19778        int numTrimming = 0;
19779
19780        mNumNonCachedProcs = 0;
19781        mNumCachedHiddenProcs = 0;
19782
19783        // First update the OOM adjustment for each of the
19784        // application processes based on their current state.
19785        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19786        int nextCachedAdj = curCachedAdj+1;
19787        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19788        int nextEmptyAdj = curEmptyAdj+2;
19789        for (int i=N-1; i>=0; i--) {
19790            ProcessRecord app = mLruProcesses.get(i);
19791            if (!app.killedByAm && app.thread != null) {
19792                app.procStateChanged = false;
19793                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19794
19795                // If we haven't yet assigned the final cached adj
19796                // to the process, do that now.
19797                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19798                    switch (app.curProcState) {
19799                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19800                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19801                            // This process is a cached process holding activities...
19802                            // assign it the next cached value for that type, and then
19803                            // step that cached level.
19804                            app.curRawAdj = curCachedAdj;
19805                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19806                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19807                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19808                                    + ")");
19809                            if (curCachedAdj != nextCachedAdj) {
19810                                stepCached++;
19811                                if (stepCached >= cachedFactor) {
19812                                    stepCached = 0;
19813                                    curCachedAdj = nextCachedAdj;
19814                                    nextCachedAdj += 2;
19815                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19816                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19817                                    }
19818                                }
19819                            }
19820                            break;
19821                        default:
19822                            // For everything else, assign next empty cached process
19823                            // level and bump that up.  Note that this means that
19824                            // long-running services that have dropped down to the
19825                            // cached level will be treated as empty (since their process
19826                            // state is still as a service), which is what we want.
19827                            app.curRawAdj = curEmptyAdj;
19828                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19829                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19830                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19831                                    + ")");
19832                            if (curEmptyAdj != nextEmptyAdj) {
19833                                stepEmpty++;
19834                                if (stepEmpty >= emptyFactor) {
19835                                    stepEmpty = 0;
19836                                    curEmptyAdj = nextEmptyAdj;
19837                                    nextEmptyAdj += 2;
19838                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19839                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19840                                    }
19841                                }
19842                            }
19843                            break;
19844                    }
19845                }
19846
19847                applyOomAdjLocked(app, true, now, nowElapsed);
19848
19849                // Count the number of process types.
19850                switch (app.curProcState) {
19851                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19852                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19853                        mNumCachedHiddenProcs++;
19854                        numCached++;
19855                        if (numCached > cachedProcessLimit) {
19856                            app.kill("cached #" + numCached, true);
19857                        }
19858                        break;
19859                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19860                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19861                                && app.lastActivityTime < oldTime) {
19862                            app.kill("empty for "
19863                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19864                                    / 1000) + "s", true);
19865                        } else {
19866                            numEmpty++;
19867                            if (numEmpty > emptyProcessLimit) {
19868                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
19869                            }
19870                        }
19871                        break;
19872                    default:
19873                        mNumNonCachedProcs++;
19874                        break;
19875                }
19876
19877                if (app.isolated && app.services.size() <= 0) {
19878                    // If this is an isolated process, and there are no
19879                    // services running in it, then the process is no longer
19880                    // needed.  We agressively kill these because we can by
19881                    // definition not re-use the same process again, and it is
19882                    // good to avoid having whatever code was running in them
19883                    // left sitting around after no longer needed.
19884                    app.kill("isolated not needed", true);
19885                } else {
19886                    // Keeping this process, update its uid.
19887                    final UidRecord uidRec = app.uidRecord;
19888                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19889                        uidRec.curProcState = app.curProcState;
19890                    }
19891                }
19892
19893                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19894                        && !app.killedByAm) {
19895                    numTrimming++;
19896                }
19897            }
19898        }
19899
19900        mNumServiceProcs = mNewNumServiceProcs;
19901
19902        // Now determine the memory trimming level of background processes.
19903        // Unfortunately we need to start at the back of the list to do this
19904        // properly.  We only do this if the number of background apps we
19905        // are managing to keep around is less than half the maximum we desire;
19906        // if we are keeping a good number around, we'll let them use whatever
19907        // memory they want.
19908        final int numCachedAndEmpty = numCached + numEmpty;
19909        int memFactor;
19910        if (numCached <= ProcessList.TRIM_CACHED_APPS
19911                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19912            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19913                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19914            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19915                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19916            } else {
19917                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19918            }
19919        } else {
19920            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19921        }
19922        // We always allow the memory level to go up (better).  We only allow it to go
19923        // down if we are in a state where that is allowed, *and* the total number of processes
19924        // has gone down since last time.
19925        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19926                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19927                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19928        if (memFactor > mLastMemoryLevel) {
19929            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19930                memFactor = mLastMemoryLevel;
19931                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19932            }
19933        }
19934        mLastMemoryLevel = memFactor;
19935        mLastNumProcesses = mLruProcesses.size();
19936        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19937        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19938        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19939            if (mLowRamStartTime == 0) {
19940                mLowRamStartTime = now;
19941            }
19942            int step = 0;
19943            int fgTrimLevel;
19944            switch (memFactor) {
19945                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19946                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19947                    break;
19948                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19949                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19950                    break;
19951                default:
19952                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19953                    break;
19954            }
19955            int factor = numTrimming/3;
19956            int minFactor = 2;
19957            if (mHomeProcess != null) minFactor++;
19958            if (mPreviousProcess != null) minFactor++;
19959            if (factor < minFactor) factor = minFactor;
19960            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19961            for (int i=N-1; i>=0; i--) {
19962                ProcessRecord app = mLruProcesses.get(i);
19963                if (allChanged || app.procStateChanged) {
19964                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19965                    app.procStateChanged = false;
19966                }
19967                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19968                        && !app.killedByAm) {
19969                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19970                        try {
19971                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19972                                    "Trimming memory of " + app.processName + " to " + curLevel);
19973                            app.thread.scheduleTrimMemory(curLevel);
19974                        } catch (RemoteException e) {
19975                        }
19976                        if (false) {
19977                            // For now we won't do this; our memory trimming seems
19978                            // to be good enough at this point that destroying
19979                            // activities causes more harm than good.
19980                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19981                                    && app != mHomeProcess && app != mPreviousProcess) {
19982                                // Need to do this on its own message because the stack may not
19983                                // be in a consistent state at this point.
19984                                // For these apps we will also finish their activities
19985                                // to help them free memory.
19986                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19987                            }
19988                        }
19989                    }
19990                    app.trimMemoryLevel = curLevel;
19991                    step++;
19992                    if (step >= factor) {
19993                        step = 0;
19994                        switch (curLevel) {
19995                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19996                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19997                                break;
19998                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19999                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20000                                break;
20001                        }
20002                    }
20003                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20004                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20005                            && app.thread != null) {
20006                        try {
20007                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20008                                    "Trimming memory of heavy-weight " + app.processName
20009                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20010                            app.thread.scheduleTrimMemory(
20011                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20012                        } catch (RemoteException e) {
20013                        }
20014                    }
20015                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20016                } else {
20017                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20018                            || app.systemNoUi) && app.pendingUiClean) {
20019                        // If this application is now in the background and it
20020                        // had done UI, then give it the special trim level to
20021                        // have it free UI resources.
20022                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20023                        if (app.trimMemoryLevel < level && app.thread != null) {
20024                            try {
20025                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20026                                        "Trimming memory of bg-ui " + app.processName
20027                                        + " to " + level);
20028                                app.thread.scheduleTrimMemory(level);
20029                            } catch (RemoteException e) {
20030                            }
20031                        }
20032                        app.pendingUiClean = false;
20033                    }
20034                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20035                        try {
20036                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20037                                    "Trimming memory of fg " + app.processName
20038                                    + " to " + fgTrimLevel);
20039                            app.thread.scheduleTrimMemory(fgTrimLevel);
20040                        } catch (RemoteException e) {
20041                        }
20042                    }
20043                    app.trimMemoryLevel = fgTrimLevel;
20044                }
20045            }
20046        } else {
20047            if (mLowRamStartTime != 0) {
20048                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20049                mLowRamStartTime = 0;
20050            }
20051            for (int i=N-1; i>=0; i--) {
20052                ProcessRecord app = mLruProcesses.get(i);
20053                if (allChanged || app.procStateChanged) {
20054                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20055                    app.procStateChanged = false;
20056                }
20057                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20058                        || app.systemNoUi) && app.pendingUiClean) {
20059                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20060                            && app.thread != null) {
20061                        try {
20062                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20063                                    "Trimming memory of ui hidden " + app.processName
20064                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20065                            app.thread.scheduleTrimMemory(
20066                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20067                        } catch (RemoteException e) {
20068                        }
20069                    }
20070                    app.pendingUiClean = false;
20071                }
20072                app.trimMemoryLevel = 0;
20073            }
20074        }
20075
20076        if (mAlwaysFinishActivities) {
20077            // Need to do this on its own message because the stack may not
20078            // be in a consistent state at this point.
20079            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20080        }
20081
20082        if (allChanged) {
20083            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20084        }
20085
20086        // Update from any uid changes.
20087        for (int i=mActiveUids.size()-1; i>=0; i--) {
20088            final UidRecord uidRec = mActiveUids.valueAt(i);
20089            int uidChange = UidRecord.CHANGE_PROCSTATE;
20090            if (uidRec.setProcState != uidRec.curProcState) {
20091                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20092                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20093                        + " to " + uidRec.curProcState);
20094                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20095                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20096                        uidRec.lastBackgroundTime = nowElapsed;
20097                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20098                            // Note: the background settle time is in elapsed realtime, while
20099                            // the handler time base is uptime.  All this means is that we may
20100                            // stop background uids later than we had intended, but that only
20101                            // happens because the device was sleeping so we are okay anyway.
20102                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20103                        }
20104                    }
20105                } else {
20106                    if (uidRec.idle) {
20107                        uidChange = UidRecord.CHANGE_ACTIVE;
20108                        uidRec.idle = false;
20109                    }
20110                    uidRec.lastBackgroundTime = 0;
20111                }
20112                uidRec.setProcState = uidRec.curProcState;
20113                enqueueUidChangeLocked(uidRec, -1, uidChange);
20114                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20115            }
20116        }
20117
20118        if (mProcessStats.shouldWriteNowLocked(now)) {
20119            mHandler.post(new Runnable() {
20120                @Override public void run() {
20121                    synchronized (ActivityManagerService.this) {
20122                        mProcessStats.writeStateAsyncLocked();
20123                    }
20124                }
20125            });
20126        }
20127
20128        if (DEBUG_OOM_ADJ) {
20129            final long duration = SystemClock.uptimeMillis() - now;
20130            if (false) {
20131                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20132                        new RuntimeException("here").fillInStackTrace());
20133            } else {
20134                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20135            }
20136        }
20137    }
20138
20139    final void idleUids() {
20140        synchronized (this) {
20141            final long nowElapsed = SystemClock.elapsedRealtime();
20142            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20143            long nextTime = 0;
20144            for (int i=mActiveUids.size()-1; i>=0; i--) {
20145                final UidRecord uidRec = mActiveUids.valueAt(i);
20146                final long bgTime = uidRec.lastBackgroundTime;
20147                if (bgTime > 0 && !uidRec.idle) {
20148                    if (bgTime <= maxBgTime) {
20149                        uidRec.idle = true;
20150                        doStopUidLocked(uidRec.uid, uidRec);
20151                    } else {
20152                        if (nextTime == 0 || nextTime > bgTime) {
20153                            nextTime = bgTime;
20154                        }
20155                    }
20156                }
20157            }
20158            if (nextTime > 0) {
20159                mHandler.removeMessages(IDLE_UIDS_MSG);
20160                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20161                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20162            }
20163        }
20164    }
20165
20166    final void runInBackgroundDisabled(int uid) {
20167        synchronized (this) {
20168            UidRecord uidRec = mActiveUids.get(uid);
20169            if (uidRec != null) {
20170                // This uid is actually running...  should it be considered background now?
20171                if (uidRec.idle) {
20172                    doStopUidLocked(uidRec.uid, uidRec);
20173                }
20174            } else {
20175                // This uid isn't actually running...  still send a report about it being "stopped".
20176                doStopUidLocked(uid, null);
20177            }
20178        }
20179    }
20180
20181    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20182        mServices.stopInBackgroundLocked(uid);
20183        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20184    }
20185
20186    final void trimApplications() {
20187        synchronized (this) {
20188            int i;
20189
20190            // First remove any unused application processes whose package
20191            // has been removed.
20192            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20193                final ProcessRecord app = mRemovedProcesses.get(i);
20194                if (app.activities.size() == 0
20195                        && app.curReceiver == null && app.services.size() == 0) {
20196                    Slog.i(
20197                        TAG, "Exiting empty application process "
20198                        + app.processName + " ("
20199                        + (app.thread != null ? app.thread.asBinder() : null)
20200                        + ")\n");
20201                    if (app.pid > 0 && app.pid != MY_PID) {
20202                        app.kill("empty", false);
20203                    } else {
20204                        try {
20205                            app.thread.scheduleExit();
20206                        } catch (Exception e) {
20207                            // Ignore exceptions.
20208                        }
20209                    }
20210                    cleanUpApplicationRecordLocked(app, false, true, -1);
20211                    mRemovedProcesses.remove(i);
20212
20213                    if (app.persistent) {
20214                        addAppLocked(app.info, false, null /* ABI override */);
20215                    }
20216                }
20217            }
20218
20219            // Now update the oom adj for all processes.
20220            updateOomAdjLocked();
20221        }
20222    }
20223
20224    /** This method sends the specified signal to each of the persistent apps */
20225    public void signalPersistentProcesses(int sig) throws RemoteException {
20226        if (sig != Process.SIGNAL_USR1) {
20227            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20228        }
20229
20230        synchronized (this) {
20231            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20232                    != PackageManager.PERMISSION_GRANTED) {
20233                throw new SecurityException("Requires permission "
20234                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20235            }
20236
20237            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20238                ProcessRecord r = mLruProcesses.get(i);
20239                if (r.thread != null && r.persistent) {
20240                    Process.sendSignal(r.pid, sig);
20241                }
20242            }
20243        }
20244    }
20245
20246    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20247        if (proc == null || proc == mProfileProc) {
20248            proc = mProfileProc;
20249            profileType = mProfileType;
20250            clearProfilerLocked();
20251        }
20252        if (proc == null) {
20253            return;
20254        }
20255        try {
20256            proc.thread.profilerControl(false, null, profileType);
20257        } catch (RemoteException e) {
20258            throw new IllegalStateException("Process disappeared");
20259        }
20260    }
20261
20262    private void clearProfilerLocked() {
20263        if (mProfileFd != null) {
20264            try {
20265                mProfileFd.close();
20266            } catch (IOException e) {
20267            }
20268        }
20269        mProfileApp = null;
20270        mProfileProc = null;
20271        mProfileFile = null;
20272        mProfileType = 0;
20273        mAutoStopProfiler = false;
20274        mSamplingInterval = 0;
20275    }
20276
20277    public boolean profileControl(String process, int userId, boolean start,
20278            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20279
20280        try {
20281            synchronized (this) {
20282                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20283                // its own permission.
20284                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20285                        != PackageManager.PERMISSION_GRANTED) {
20286                    throw new SecurityException("Requires permission "
20287                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20288                }
20289
20290                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20291                    throw new IllegalArgumentException("null profile info or fd");
20292                }
20293
20294                ProcessRecord proc = null;
20295                if (process != null) {
20296                    proc = findProcessLocked(process, userId, "profileControl");
20297                }
20298
20299                if (start && (proc == null || proc.thread == null)) {
20300                    throw new IllegalArgumentException("Unknown process: " + process);
20301                }
20302
20303                if (start) {
20304                    stopProfilerLocked(null, 0);
20305                    setProfileApp(proc.info, proc.processName, profilerInfo);
20306                    mProfileProc = proc;
20307                    mProfileType = profileType;
20308                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20309                    try {
20310                        fd = fd.dup();
20311                    } catch (IOException e) {
20312                        fd = null;
20313                    }
20314                    profilerInfo.profileFd = fd;
20315                    proc.thread.profilerControl(start, profilerInfo, profileType);
20316                    fd = null;
20317                    mProfileFd = null;
20318                } else {
20319                    stopProfilerLocked(proc, profileType);
20320                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20321                        try {
20322                            profilerInfo.profileFd.close();
20323                        } catch (IOException e) {
20324                        }
20325                    }
20326                }
20327
20328                return true;
20329            }
20330        } catch (RemoteException e) {
20331            throw new IllegalStateException("Process disappeared");
20332        } finally {
20333            if (profilerInfo != null && profilerInfo.profileFd != null) {
20334                try {
20335                    profilerInfo.profileFd.close();
20336                } catch (IOException e) {
20337                }
20338            }
20339        }
20340    }
20341
20342    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20343        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20344                userId, true, ALLOW_FULL_ONLY, callName, null);
20345        ProcessRecord proc = null;
20346        try {
20347            int pid = Integer.parseInt(process);
20348            synchronized (mPidsSelfLocked) {
20349                proc = mPidsSelfLocked.get(pid);
20350            }
20351        } catch (NumberFormatException e) {
20352        }
20353
20354        if (proc == null) {
20355            ArrayMap<String, SparseArray<ProcessRecord>> all
20356                    = mProcessNames.getMap();
20357            SparseArray<ProcessRecord> procs = all.get(process);
20358            if (procs != null && procs.size() > 0) {
20359                proc = procs.valueAt(0);
20360                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20361                    for (int i=1; i<procs.size(); i++) {
20362                        ProcessRecord thisProc = procs.valueAt(i);
20363                        if (thisProc.userId == userId) {
20364                            proc = thisProc;
20365                            break;
20366                        }
20367                    }
20368                }
20369            }
20370        }
20371
20372        return proc;
20373    }
20374
20375    public boolean dumpHeap(String process, int userId, boolean managed,
20376            String path, ParcelFileDescriptor fd) throws RemoteException {
20377
20378        try {
20379            synchronized (this) {
20380                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20381                // its own permission (same as profileControl).
20382                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20383                        != PackageManager.PERMISSION_GRANTED) {
20384                    throw new SecurityException("Requires permission "
20385                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20386                }
20387
20388                if (fd == null) {
20389                    throw new IllegalArgumentException("null fd");
20390                }
20391
20392                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20393                if (proc == null || proc.thread == null) {
20394                    throw new IllegalArgumentException("Unknown process: " + process);
20395                }
20396
20397                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20398                if (!isDebuggable) {
20399                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20400                        throw new SecurityException("Process not debuggable: " + proc);
20401                    }
20402                }
20403
20404                proc.thread.dumpHeap(managed, path, fd);
20405                fd = null;
20406                return true;
20407            }
20408        } catch (RemoteException e) {
20409            throw new IllegalStateException("Process disappeared");
20410        } finally {
20411            if (fd != null) {
20412                try {
20413                    fd.close();
20414                } catch (IOException e) {
20415                }
20416            }
20417        }
20418    }
20419
20420    @Override
20421    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20422            String reportPackage) {
20423        if (processName != null) {
20424            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20425                    "setDumpHeapDebugLimit()");
20426        } else {
20427            synchronized (mPidsSelfLocked) {
20428                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20429                if (proc == null) {
20430                    throw new SecurityException("No process found for calling pid "
20431                            + Binder.getCallingPid());
20432                }
20433                if (!Build.IS_DEBUGGABLE
20434                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20435                    throw new SecurityException("Not running a debuggable build");
20436                }
20437                processName = proc.processName;
20438                uid = proc.uid;
20439                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20440                    throw new SecurityException("Package " + reportPackage + " is not running in "
20441                            + proc);
20442                }
20443            }
20444        }
20445        synchronized (this) {
20446            if (maxMemSize > 0) {
20447                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20448            } else {
20449                if (uid != 0) {
20450                    mMemWatchProcesses.remove(processName, uid);
20451                } else {
20452                    mMemWatchProcesses.getMap().remove(processName);
20453                }
20454            }
20455        }
20456    }
20457
20458    @Override
20459    public void dumpHeapFinished(String path) {
20460        synchronized (this) {
20461            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20462                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20463                        + " does not match last pid " + mMemWatchDumpPid);
20464                return;
20465            }
20466            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20467                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20468                        + " does not match last path " + mMemWatchDumpFile);
20469                return;
20470            }
20471            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20472            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20473        }
20474    }
20475
20476    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20477    public void monitor() {
20478        synchronized (this) { }
20479    }
20480
20481    void onCoreSettingsChange(Bundle settings) {
20482        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20483            ProcessRecord processRecord = mLruProcesses.get(i);
20484            try {
20485                if (processRecord.thread != null) {
20486                    processRecord.thread.setCoreSettings(settings);
20487                }
20488            } catch (RemoteException re) {
20489                /* ignore */
20490            }
20491        }
20492    }
20493
20494    // Multi-user methods
20495
20496    /**
20497     * Start user, if its not already running, but don't bring it to foreground.
20498     */
20499    @Override
20500    public boolean startUserInBackground(final int userId) {
20501        return mUserController.startUser(userId, /* foreground */ false);
20502    }
20503
20504    @Override
20505    public boolean unlockUser(int userId, byte[] token, byte[] secret) {
20506        return mUserController.unlockUser(userId, token, secret);
20507    }
20508
20509    @Override
20510    public boolean switchUser(final int targetUserId) {
20511        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20512        UserInfo currentUserInfo;
20513        UserInfo targetUserInfo;
20514        synchronized (this) {
20515            int currentUserId = mUserController.getCurrentUserIdLocked();
20516            currentUserInfo = mUserController.getUserInfo(currentUserId);
20517            targetUserInfo = mUserController.getUserInfo(targetUserId);
20518            if (targetUserInfo == null) {
20519                Slog.w(TAG, "No user info for user #" + targetUserId);
20520                return false;
20521            }
20522            if (!targetUserInfo.supportsSwitchTo()) {
20523                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20524                return false;
20525            }
20526            if (targetUserInfo.isManagedProfile()) {
20527                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20528                return false;
20529            }
20530            mUserController.setTargetUserIdLocked(targetUserId);
20531        }
20532        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20533        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20534        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20535        return true;
20536    }
20537
20538    void scheduleStartProfilesLocked() {
20539        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20540            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20541                    DateUtils.SECOND_IN_MILLIS);
20542        }
20543    }
20544
20545    @Override
20546    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20547        return mUserController.stopUser(userId, force, callback);
20548    }
20549
20550    @Override
20551    public UserInfo getCurrentUser() {
20552        return mUserController.getCurrentUser();
20553    }
20554
20555    @Override
20556    public boolean isUserRunning(int userId, int flags) {
20557        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20558                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20559            String msg = "Permission Denial: isUserRunning() from pid="
20560                    + Binder.getCallingPid()
20561                    + ", uid=" + Binder.getCallingUid()
20562                    + " requires " + INTERACT_ACROSS_USERS;
20563            Slog.w(TAG, msg);
20564            throw new SecurityException(msg);
20565        }
20566        synchronized (this) {
20567            return mUserController.isUserRunningLocked(userId, flags);
20568        }
20569    }
20570
20571    @Override
20572    public int[] getRunningUserIds() {
20573        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20574                != PackageManager.PERMISSION_GRANTED) {
20575            String msg = "Permission Denial: isUserRunning() from pid="
20576                    + Binder.getCallingPid()
20577                    + ", uid=" + Binder.getCallingUid()
20578                    + " requires " + INTERACT_ACROSS_USERS;
20579            Slog.w(TAG, msg);
20580            throw new SecurityException(msg);
20581        }
20582        synchronized (this) {
20583            return mUserController.getStartedUserArrayLocked();
20584        }
20585    }
20586
20587    @Override
20588    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20589        mUserController.registerUserSwitchObserver(observer);
20590    }
20591
20592    @Override
20593    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20594        mUserController.unregisterUserSwitchObserver(observer);
20595    }
20596
20597    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20598        if (info == null) return null;
20599        ApplicationInfo newInfo = new ApplicationInfo(info);
20600        newInfo.initForUser(userId);
20601        return newInfo;
20602    }
20603
20604    public boolean isUserStopped(int userId) {
20605        synchronized (this) {
20606            return mUserController.getStartedUserStateLocked(userId) == null;
20607        }
20608    }
20609
20610    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20611        if (aInfo == null
20612                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20613            return aInfo;
20614        }
20615
20616        ActivityInfo info = new ActivityInfo(aInfo);
20617        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20618        return info;
20619    }
20620
20621    private boolean processSanityChecksLocked(ProcessRecord process) {
20622        if (process == null || process.thread == null) {
20623            return false;
20624        }
20625
20626        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20627        if (!isDebuggable) {
20628            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20629                return false;
20630            }
20631        }
20632
20633        return true;
20634    }
20635
20636    public boolean startBinderTracking() throws RemoteException {
20637        synchronized (this) {
20638            mBinderTransactionTrackingEnabled = true;
20639            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20640            // permission (same as profileControl).
20641            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20642                    != PackageManager.PERMISSION_GRANTED) {
20643                throw new SecurityException("Requires permission "
20644                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20645            }
20646
20647            for (int i = 0; i < mLruProcesses.size(); i++) {
20648                ProcessRecord process = mLruProcesses.get(i);
20649                if (!processSanityChecksLocked(process)) {
20650                    continue;
20651                }
20652                try {
20653                    process.thread.startBinderTracking();
20654                } catch (RemoteException e) {
20655                    Log.v(TAG, "Process disappared");
20656                }
20657            }
20658            return true;
20659        }
20660    }
20661
20662    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20663        try {
20664            synchronized (this) {
20665                mBinderTransactionTrackingEnabled = false;
20666                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20667                // permission (same as profileControl).
20668                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20669                        != PackageManager.PERMISSION_GRANTED) {
20670                    throw new SecurityException("Requires permission "
20671                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20672                }
20673
20674                if (fd == null) {
20675                    throw new IllegalArgumentException("null fd");
20676                }
20677
20678                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20679                pw.println("Binder transaction traces for all processes.\n");
20680                for (ProcessRecord process : mLruProcesses) {
20681                    if (!processSanityChecksLocked(process)) {
20682                        continue;
20683                    }
20684
20685                    pw.println("Traces for process: " + process.processName);
20686                    pw.flush();
20687                    try {
20688                        TransferPipe tp = new TransferPipe();
20689                        try {
20690                            process.thread.stopBinderTrackingAndDump(
20691                                    tp.getWriteFd().getFileDescriptor());
20692                            tp.go(fd.getFileDescriptor());
20693                        } finally {
20694                            tp.kill();
20695                        }
20696                    } catch (IOException e) {
20697                        pw.println("Failure while dumping IPC traces from " + process +
20698                                ".  Exception: " + e);
20699                        pw.flush();
20700                    } catch (RemoteException e) {
20701                        pw.println("Got a RemoteException while dumping IPC traces from " +
20702                                process + ".  Exception: " + e);
20703                        pw.flush();
20704                    }
20705                }
20706                fd = null;
20707                return true;
20708            }
20709        } finally {
20710            if (fd != null) {
20711                try {
20712                    fd.close();
20713                } catch (IOException e) {
20714                }
20715            }
20716        }
20717    }
20718
20719    private final class LocalService extends ActivityManagerInternal {
20720        @Override
20721        public void onWakefulnessChanged(int wakefulness) {
20722            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20723        }
20724
20725        @Override
20726        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20727                String processName, String abiOverride, int uid, Runnable crashHandler) {
20728            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20729                    processName, abiOverride, uid, crashHandler);
20730        }
20731
20732        @Override
20733        public SleepToken acquireSleepToken(String tag) {
20734            Preconditions.checkNotNull(tag);
20735
20736            synchronized (ActivityManagerService.this) {
20737                SleepTokenImpl token = new SleepTokenImpl(tag);
20738                mSleepTokens.add(token);
20739                updateSleepIfNeededLocked();
20740                return token;
20741            }
20742        }
20743
20744        @Override
20745        public ComponentName getHomeActivityForUser(int userId) {
20746            synchronized (ActivityManagerService.this) {
20747                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20748                return homeActivity == null ? null : homeActivity.realActivity;
20749            }
20750        }
20751
20752        @Override
20753        public void onUserRemoved(int userId) {
20754            synchronized (ActivityManagerService.this) {
20755                ActivityManagerService.this.onUserStoppedLocked(userId);
20756            }
20757        }
20758
20759        @Override
20760        public void onLocalVoiceInteractionStarted(IBinder activity,
20761                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20762            synchronized (ActivityManagerService.this) {
20763                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20764                        voiceSession, voiceInteractor);
20765            }
20766        }
20767
20768        @Override
20769        public void notifyStartingWindowDrawn() {
20770            synchronized (ActivityManagerService.this) {
20771                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20772            }
20773        }
20774
20775        @Override
20776        public void notifyAppTransitionStarting(int reason) {
20777            synchronized (ActivityManagerService.this) {
20778                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20779            }
20780        }
20781    }
20782
20783    private final class SleepTokenImpl extends SleepToken {
20784        private final String mTag;
20785        private final long mAcquireTime;
20786
20787        public SleepTokenImpl(String tag) {
20788            mTag = tag;
20789            mAcquireTime = SystemClock.uptimeMillis();
20790        }
20791
20792        @Override
20793        public void release() {
20794            synchronized (ActivityManagerService.this) {
20795                if (mSleepTokens.remove(this)) {
20796                    updateSleepIfNeededLocked();
20797                }
20798            }
20799        }
20800
20801        @Override
20802        public String toString() {
20803            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20804        }
20805    }
20806
20807    /**
20808     * An implementation of IAppTask, that allows an app to manage its own tasks via
20809     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20810     * only the process that calls getAppTasks() can call the AppTask methods.
20811     */
20812    class AppTaskImpl extends IAppTask.Stub {
20813        private int mTaskId;
20814        private int mCallingUid;
20815
20816        public AppTaskImpl(int taskId, int callingUid) {
20817            mTaskId = taskId;
20818            mCallingUid = callingUid;
20819        }
20820
20821        private void checkCaller() {
20822            if (mCallingUid != Binder.getCallingUid()) {
20823                throw new SecurityException("Caller " + mCallingUid
20824                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20825            }
20826        }
20827
20828        @Override
20829        public void finishAndRemoveTask() {
20830            checkCaller();
20831
20832            synchronized (ActivityManagerService.this) {
20833                long origId = Binder.clearCallingIdentity();
20834                try {
20835                    // We remove the task from recents to preserve backwards
20836                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20837                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20838                    }
20839                } finally {
20840                    Binder.restoreCallingIdentity(origId);
20841                }
20842            }
20843        }
20844
20845        @Override
20846        public ActivityManager.RecentTaskInfo getTaskInfo() {
20847            checkCaller();
20848
20849            synchronized (ActivityManagerService.this) {
20850                long origId = Binder.clearCallingIdentity();
20851                try {
20852                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20853                    if (tr == null) {
20854                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20855                    }
20856                    return createRecentTaskInfoFromTaskRecord(tr);
20857                } finally {
20858                    Binder.restoreCallingIdentity(origId);
20859                }
20860            }
20861        }
20862
20863        @Override
20864        public void moveToFront() {
20865            checkCaller();
20866            // Will bring task to front if it already has a root activity.
20867            final long origId = Binder.clearCallingIdentity();
20868            try {
20869                startActivityFromRecentsInner(mTaskId, null);
20870            } finally {
20871                Binder.restoreCallingIdentity(origId);
20872            }
20873        }
20874
20875        @Override
20876        public int startActivity(IBinder whoThread, String callingPackage,
20877                Intent intent, String resolvedType, Bundle bOptions) {
20878            checkCaller();
20879
20880            int callingUser = UserHandle.getCallingUserId();
20881            TaskRecord tr;
20882            IApplicationThread appThread;
20883            synchronized (ActivityManagerService.this) {
20884                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20885                if (tr == null) {
20886                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20887                }
20888                appThread = ApplicationThreadNative.asInterface(whoThread);
20889                if (appThread == null) {
20890                    throw new IllegalArgumentException("Bad app thread " + appThread);
20891                }
20892            }
20893            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
20894                    resolvedType, null, null, null, null, 0, 0, null, null,
20895                    null, bOptions, false, callingUser, null, tr);
20896        }
20897
20898        @Override
20899        public void setExcludeFromRecents(boolean exclude) {
20900            checkCaller();
20901
20902            synchronized (ActivityManagerService.this) {
20903                long origId = Binder.clearCallingIdentity();
20904                try {
20905                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20906                    if (tr == null) {
20907                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20908                    }
20909                    Intent intent = tr.getBaseIntent();
20910                    if (exclude) {
20911                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20912                    } else {
20913                        intent.setFlags(intent.getFlags()
20914                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20915                    }
20916                } finally {
20917                    Binder.restoreCallingIdentity(origId);
20918                }
20919            }
20920        }
20921    }
20922
20923    /**
20924     * Kill processes for the user with id userId and that depend on the package named packageName
20925     */
20926    @Override
20927    public void killPackageDependents(String packageName, int userId) {
20928        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
20929        if (packageName == null) {
20930            throw new NullPointerException(
20931                    "Cannot kill the dependents of a package without its name.");
20932        }
20933
20934        long callingId = Binder.clearCallingIdentity();
20935        IPackageManager pm = AppGlobals.getPackageManager();
20936        int pkgUid = -1;
20937        try {
20938            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
20939        } catch (RemoteException e) {
20940        }
20941        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
20942            throw new IllegalArgumentException(
20943                    "Cannot kill dependents of non-existing package " + packageName);
20944        }
20945        try {
20946            synchronized(this) {
20947                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
20948                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
20949                        "dep: " + packageName);
20950            }
20951        } finally {
20952            Binder.restoreCallingIdentity(callingId);
20953        }
20954    }
20955}
20956