ActivityManagerService.java revision 414c529a4f3d8aa50df6e3615d2084ac1089de85
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 void 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                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9499                        "moveTaskToDockedStack", animate);
9500            } finally {
9501                Binder.restoreCallingIdentity(ident);
9502            }
9503        }
9504    }
9505
9506    /**
9507     * Moves the top activity in the input stackId to the pinned stack.
9508     *
9509     * @param stackId Id of stack to move the top activity to pinned stack.
9510     * @param bounds Bounds to use for pinned stack.
9511     *
9512     * @return True if the top activity of the input stack was successfully moved to the pinned
9513     *          stack.
9514     */
9515    @Override
9516    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9517        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9518        synchronized (this) {
9519            if (!mSupportsPictureInPicture) {
9520                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9521                        + "Device doesn't support picture-in-pciture mode");
9522            }
9523
9524            long ident = Binder.clearCallingIdentity();
9525            try {
9526                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9527            } finally {
9528                Binder.restoreCallingIdentity(ident);
9529            }
9530        }
9531    }
9532
9533    @Override
9534    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9535            boolean preserveWindows, boolean animate) {
9536        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9537        long ident = Binder.clearCallingIdentity();
9538        try {
9539            synchronized (this) {
9540                if (animate) {
9541                    if (stackId == PINNED_STACK_ID) {
9542                        mWindowManager.animateResizePinnedStack(bounds);
9543                    } else {
9544                        throw new IllegalArgumentException("Stack: " + stackId
9545                                + " doesn't support animated resize.");
9546                    }
9547                } else {
9548                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9549                            null /* tempTaskInsetBounds */, preserveWindows,
9550                            allowResizeInDockedMode);
9551                }
9552            }
9553        } finally {
9554            Binder.restoreCallingIdentity(ident);
9555        }
9556    }
9557
9558    @Override
9559    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9560            Rect tempDockedTaskInsetBounds,
9561            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9562        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9563                "resizeDockedStack()");
9564        long ident = Binder.clearCallingIdentity();
9565        try {
9566            synchronized (this) {
9567                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9568                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9569                        PRESERVE_WINDOWS);
9570            }
9571        } finally {
9572            Binder.restoreCallingIdentity(ident);
9573        }
9574    }
9575
9576    @Override
9577    public void positionTaskInStack(int taskId, int stackId, int position) {
9578        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9579        if (stackId == HOME_STACK_ID) {
9580            throw new IllegalArgumentException(
9581                    "positionTaskInStack: Attempt to change the position of task "
9582                    + taskId + " in/to home stack");
9583        }
9584        synchronized (this) {
9585            long ident = Binder.clearCallingIdentity();
9586            try {
9587                if (DEBUG_STACK) Slog.d(TAG_STACK,
9588                        "positionTaskInStack: positioning task=" + taskId
9589                        + " in stackId=" + stackId + " at position=" + position);
9590                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9591            } finally {
9592                Binder.restoreCallingIdentity(ident);
9593            }
9594        }
9595    }
9596
9597    @Override
9598    public List<StackInfo> getAllStackInfos() {
9599        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9600        long ident = Binder.clearCallingIdentity();
9601        try {
9602            synchronized (this) {
9603                return mStackSupervisor.getAllStackInfosLocked();
9604            }
9605        } finally {
9606            Binder.restoreCallingIdentity(ident);
9607        }
9608    }
9609
9610    @Override
9611    public StackInfo getStackInfo(int stackId) {
9612        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9613        long ident = Binder.clearCallingIdentity();
9614        try {
9615            synchronized (this) {
9616                return mStackSupervisor.getStackInfoLocked(stackId);
9617            }
9618        } finally {
9619            Binder.restoreCallingIdentity(ident);
9620        }
9621    }
9622
9623    @Override
9624    public boolean isInHomeStack(int taskId) {
9625        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9626        long ident = Binder.clearCallingIdentity();
9627        try {
9628            synchronized (this) {
9629                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9630                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9631                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9632            }
9633        } finally {
9634            Binder.restoreCallingIdentity(ident);
9635        }
9636    }
9637
9638    @Override
9639    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9640        synchronized(this) {
9641            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9642        }
9643    }
9644
9645    @Override
9646    public void updateDeviceOwner(String packageName) {
9647        final int callingUid = Binder.getCallingUid();
9648        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9649            throw new SecurityException("updateDeviceOwner called from non-system process");
9650        }
9651        synchronized (this) {
9652            mDeviceOwnerName = packageName;
9653        }
9654    }
9655
9656    @Override
9657    public void updateLockTaskPackages(int userId, String[] packages) {
9658        final int callingUid = Binder.getCallingUid();
9659        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9660            throw new SecurityException("updateLockTaskPackage called from non-system process");
9661        }
9662        synchronized (this) {
9663            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9664                    Arrays.toString(packages));
9665            mLockTaskPackages.put(userId, packages);
9666            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9667        }
9668    }
9669
9670
9671    void startLockTaskModeLocked(TaskRecord task) {
9672        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9673        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9674            return;
9675        }
9676
9677        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9678        // is initiated by system after the pinning request was shown and locked mode is initiated
9679        // by an authorized app directly
9680        final int callingUid = Binder.getCallingUid();
9681        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9682        long ident = Binder.clearCallingIdentity();
9683        try {
9684            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9685            if (!isSystemInitiated) {
9686                task.mLockTaskUid = callingUid;
9687                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9688                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9689                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9690                    StatusBarManagerInternal statusBarManager =
9691                            LocalServices.getService(StatusBarManagerInternal.class);
9692                    if (statusBarManager != null) {
9693                        statusBarManager.showScreenPinningRequest();
9694                    }
9695                    return;
9696                }
9697
9698                if (stack == null || task != stack.topTask()) {
9699                    throw new IllegalArgumentException("Invalid task, not in foreground");
9700                }
9701            }
9702            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9703                    "Locking fully");
9704            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9705                    ActivityManager.LOCK_TASK_MODE_PINNED :
9706                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9707                    "startLockTask", true);
9708        } finally {
9709            Binder.restoreCallingIdentity(ident);
9710        }
9711    }
9712
9713    @Override
9714    public void startLockTaskMode(int taskId) {
9715        synchronized (this) {
9716            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9717            if (task != null) {
9718                startLockTaskModeLocked(task);
9719            }
9720        }
9721    }
9722
9723    @Override
9724    public void startLockTaskMode(IBinder token) {
9725        synchronized (this) {
9726            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9727            if (r == null) {
9728                return;
9729            }
9730            final TaskRecord task = r.task;
9731            if (task != null) {
9732                startLockTaskModeLocked(task);
9733            }
9734        }
9735    }
9736
9737    @Override
9738    public void startLockTaskModeOnCurrent() throws RemoteException {
9739        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9740        long ident = Binder.clearCallingIdentity();
9741        try {
9742            synchronized (this) {
9743                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9744                if (r != null) {
9745                    startLockTaskModeLocked(r.task);
9746                }
9747            }
9748        } finally {
9749            Binder.restoreCallingIdentity(ident);
9750        }
9751    }
9752
9753    @Override
9754    public void stopLockTaskMode() {
9755        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9756        if (lockTask == null) {
9757            // Our work here is done.
9758            return;
9759        }
9760
9761        final int callingUid = Binder.getCallingUid();
9762        final int lockTaskUid = lockTask.mLockTaskUid;
9763        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9764        // It is possible lockTaskMode was started by the system process because
9765        // android:lockTaskMode is set to a locking value in the application manifest instead of
9766        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9767        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9768        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9769                callingUid != lockTaskUid
9770                && (lockTaskUid != 0
9771                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9772            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9773                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9774        }
9775
9776        long ident = Binder.clearCallingIdentity();
9777        try {
9778            Log.d(TAG, "stopLockTaskMode");
9779            // Stop lock task
9780            synchronized (this) {
9781                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9782                        "stopLockTask", true);
9783            }
9784        } finally {
9785            Binder.restoreCallingIdentity(ident);
9786        }
9787    }
9788
9789    @Override
9790    public void stopLockTaskModeOnCurrent() throws RemoteException {
9791        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9792        long ident = Binder.clearCallingIdentity();
9793        try {
9794            stopLockTaskMode();
9795        } finally {
9796            Binder.restoreCallingIdentity(ident);
9797        }
9798    }
9799
9800    @Override
9801    public boolean isInLockTaskMode() {
9802        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9803    }
9804
9805    @Override
9806    public int getLockTaskModeState() {
9807        synchronized (this) {
9808            return mStackSupervisor.getLockTaskModeState();
9809        }
9810    }
9811
9812    @Override
9813    public void showLockTaskEscapeMessage(IBinder token) {
9814        synchronized (this) {
9815            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9816            if (r == null) {
9817                return;
9818            }
9819            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9820        }
9821    }
9822
9823    // =========================================================
9824    // CONTENT PROVIDERS
9825    // =========================================================
9826
9827    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9828        List<ProviderInfo> providers = null;
9829        try {
9830            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9831                    .queryContentProviders(app.processName, app.uid,
9832                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9833                                    | MATCH_DEBUG_TRIAGED_MISSING);
9834            providers = slice != null ? slice.getList() : null;
9835        } catch (RemoteException ex) {
9836        }
9837        if (DEBUG_MU) Slog.v(TAG_MU,
9838                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9839        int userId = app.userId;
9840        if (providers != null) {
9841            int N = providers.size();
9842            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9843            for (int i=0; i<N; i++) {
9844                ProviderInfo cpi =
9845                    (ProviderInfo)providers.get(i);
9846                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9847                        cpi.name, cpi.flags);
9848                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9849                    // This is a singleton provider, but a user besides the
9850                    // default user is asking to initialize a process it runs
9851                    // in...  well, no, it doesn't actually run in this process,
9852                    // it runs in the process of the default user.  Get rid of it.
9853                    providers.remove(i);
9854                    N--;
9855                    i--;
9856                    continue;
9857                }
9858
9859                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9860                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9861                if (cpr == null) {
9862                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9863                    mProviderMap.putProviderByClass(comp, cpr);
9864                }
9865                if (DEBUG_MU) Slog.v(TAG_MU,
9866                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9867                app.pubProviders.put(cpi.name, cpr);
9868                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9869                    // Don't add this if it is a platform component that is marked
9870                    // to run in multiple processes, because this is actually
9871                    // part of the framework so doesn't make sense to track as a
9872                    // separate apk in the process.
9873                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9874                            mProcessStats);
9875                }
9876                notifyPackageUse(cpi.applicationInfo.packageName);
9877            }
9878        }
9879        return providers;
9880    }
9881
9882    /**
9883     * Check if {@link ProcessRecord} has a possible chance at accessing the
9884     * given {@link ProviderInfo}. Final permission checking is always done
9885     * in {@link ContentProvider}.
9886     */
9887    private final String checkContentProviderPermissionLocked(
9888            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9889        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9890        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9891        boolean checkedGrants = false;
9892        if (checkUser) {
9893            // Looking for cross-user grants before enforcing the typical cross-users permissions
9894            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9895            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9896                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9897                    return null;
9898                }
9899                checkedGrants = true;
9900            }
9901            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9902                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9903            if (userId != tmpTargetUserId) {
9904                // When we actually went to determine the final targer user ID, this ended
9905                // up different than our initial check for the authority.  This is because
9906                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9907                // SELF.  So we need to re-check the grants again.
9908                checkedGrants = false;
9909            }
9910        }
9911        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9912                cpi.applicationInfo.uid, cpi.exported)
9913                == PackageManager.PERMISSION_GRANTED) {
9914            return null;
9915        }
9916        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9917                cpi.applicationInfo.uid, cpi.exported)
9918                == PackageManager.PERMISSION_GRANTED) {
9919            return null;
9920        }
9921
9922        PathPermission[] pps = cpi.pathPermissions;
9923        if (pps != null) {
9924            int i = pps.length;
9925            while (i > 0) {
9926                i--;
9927                PathPermission pp = pps[i];
9928                String pprperm = pp.getReadPermission();
9929                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9930                        cpi.applicationInfo.uid, cpi.exported)
9931                        == PackageManager.PERMISSION_GRANTED) {
9932                    return null;
9933                }
9934                String ppwperm = pp.getWritePermission();
9935                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9936                        cpi.applicationInfo.uid, cpi.exported)
9937                        == PackageManager.PERMISSION_GRANTED) {
9938                    return null;
9939                }
9940            }
9941        }
9942        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9943            return null;
9944        }
9945
9946        String msg;
9947        if (!cpi.exported) {
9948            msg = "Permission Denial: opening provider " + cpi.name
9949                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9950                    + ", uid=" + callingUid + ") that is not exported from uid "
9951                    + cpi.applicationInfo.uid;
9952        } else {
9953            msg = "Permission Denial: opening provider " + cpi.name
9954                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9955                    + ", uid=" + callingUid + ") requires "
9956                    + cpi.readPermission + " or " + cpi.writePermission;
9957        }
9958        Slog.w(TAG, msg);
9959        return msg;
9960    }
9961
9962    /**
9963     * Returns if the ContentProvider has granted a uri to callingUid
9964     */
9965    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9966        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9967        if (perms != null) {
9968            for (int i=perms.size()-1; i>=0; i--) {
9969                GrantUri grantUri = perms.keyAt(i);
9970                if (grantUri.sourceUserId == userId || !checkUser) {
9971                    if (matchesProvider(grantUri.uri, cpi)) {
9972                        return true;
9973                    }
9974                }
9975            }
9976        }
9977        return false;
9978    }
9979
9980    /**
9981     * Returns true if the uri authority is one of the authorities specified in the provider.
9982     */
9983    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9984        String uriAuth = uri.getAuthority();
9985        String cpiAuth = cpi.authority;
9986        if (cpiAuth.indexOf(';') == -1) {
9987            return cpiAuth.equals(uriAuth);
9988        }
9989        String[] cpiAuths = cpiAuth.split(";");
9990        int length = cpiAuths.length;
9991        for (int i = 0; i < length; i++) {
9992            if (cpiAuths[i].equals(uriAuth)) return true;
9993        }
9994        return false;
9995    }
9996
9997    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9998            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9999        if (r != null) {
10000            for (int i=0; i<r.conProviders.size(); i++) {
10001                ContentProviderConnection conn = r.conProviders.get(i);
10002                if (conn.provider == cpr) {
10003                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10004                            "Adding provider requested by "
10005                            + r.processName + " from process "
10006                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10007                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10008                    if (stable) {
10009                        conn.stableCount++;
10010                        conn.numStableIncs++;
10011                    } else {
10012                        conn.unstableCount++;
10013                        conn.numUnstableIncs++;
10014                    }
10015                    return conn;
10016                }
10017            }
10018            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10019            if (stable) {
10020                conn.stableCount = 1;
10021                conn.numStableIncs = 1;
10022            } else {
10023                conn.unstableCount = 1;
10024                conn.numUnstableIncs = 1;
10025            }
10026            cpr.connections.add(conn);
10027            r.conProviders.add(conn);
10028            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10029            return conn;
10030        }
10031        cpr.addExternalProcessHandleLocked(externalProcessToken);
10032        return null;
10033    }
10034
10035    boolean decProviderCountLocked(ContentProviderConnection conn,
10036            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10037        if (conn != null) {
10038            cpr = conn.provider;
10039            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10040                    "Removing provider requested by "
10041                    + conn.client.processName + " from process "
10042                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10043                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10044            if (stable) {
10045                conn.stableCount--;
10046            } else {
10047                conn.unstableCount--;
10048            }
10049            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10050                cpr.connections.remove(conn);
10051                conn.client.conProviders.remove(conn);
10052                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10053                    // The client is more important than last activity -- note the time this
10054                    // is happening, so we keep the old provider process around a bit as last
10055                    // activity to avoid thrashing it.
10056                    if (cpr.proc != null) {
10057                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10058                    }
10059                }
10060                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10061                return true;
10062            }
10063            return false;
10064        }
10065        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10066        return false;
10067    }
10068
10069    private void checkTime(long startTime, String where) {
10070        long now = SystemClock.elapsedRealtime();
10071        if ((now-startTime) > 1000) {
10072            // If we are taking more than a second, log about it.
10073            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10074        }
10075    }
10076
10077    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10078            String name, IBinder token, boolean stable, int userId) {
10079        ContentProviderRecord cpr;
10080        ContentProviderConnection conn = null;
10081        ProviderInfo cpi = null;
10082
10083        synchronized(this) {
10084            long startTime = SystemClock.elapsedRealtime();
10085
10086            ProcessRecord r = null;
10087            if (caller != null) {
10088                r = getRecordForAppLocked(caller);
10089                if (r == null) {
10090                    throw new SecurityException(
10091                            "Unable to find app for caller " + caller
10092                          + " (pid=" + Binder.getCallingPid()
10093                          + ") when getting content provider " + name);
10094                }
10095            }
10096
10097            boolean checkCrossUser = true;
10098
10099            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10100
10101            // First check if this content provider has been published...
10102            cpr = mProviderMap.getProviderByName(name, userId);
10103            // If that didn't work, check if it exists for user 0 and then
10104            // verify that it's a singleton provider before using it.
10105            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10106                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10107                if (cpr != null) {
10108                    cpi = cpr.info;
10109                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10110                            cpi.name, cpi.flags)
10111                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10112                        userId = UserHandle.USER_SYSTEM;
10113                        checkCrossUser = false;
10114                    } else {
10115                        cpr = null;
10116                        cpi = null;
10117                    }
10118                }
10119            }
10120
10121            boolean providerRunning = cpr != null;
10122            if (providerRunning) {
10123                cpi = cpr.info;
10124                String msg;
10125                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10126                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10127                        != null) {
10128                    throw new SecurityException(msg);
10129                }
10130                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10131
10132                if (r != null && cpr.canRunHere(r)) {
10133                    // This provider has been published or is in the process
10134                    // of being published...  but it is also allowed to run
10135                    // in the caller's process, so don't make a connection
10136                    // and just let the caller instantiate its own instance.
10137                    ContentProviderHolder holder = cpr.newHolder(null);
10138                    // don't give caller the provider object, it needs
10139                    // to make its own.
10140                    holder.provider = null;
10141                    return holder;
10142                }
10143
10144                final long origId = Binder.clearCallingIdentity();
10145
10146                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10147
10148                // In this case the provider instance already exists, so we can
10149                // return it right away.
10150                conn = incProviderCountLocked(r, cpr, token, stable);
10151                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10152                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10153                        // If this is a perceptible app accessing the provider,
10154                        // make sure to count it as being accessed and thus
10155                        // back up on the LRU list.  This is good because
10156                        // content providers are often expensive to start.
10157                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10158                        updateLruProcessLocked(cpr.proc, false, null);
10159                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10160                    }
10161                }
10162
10163                if (cpr.proc != null) {
10164                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10165                    boolean success = updateOomAdjLocked(cpr.proc);
10166                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10167                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10168                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10169                    // NOTE: there is still a race here where a signal could be
10170                    // pending on the process even though we managed to update its
10171                    // adj level.  Not sure what to do about this, but at least
10172                    // the race is now smaller.
10173                    if (!success) {
10174                        // Uh oh...  it looks like the provider's process
10175                        // has been killed on us.  We need to wait for a new
10176                        // process to be started, and make sure its death
10177                        // doesn't kill our process.
10178                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10179                                + " is crashing; detaching " + r);
10180                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10181                        checkTime(startTime, "getContentProviderImpl: before appDied");
10182                        appDiedLocked(cpr.proc);
10183                        checkTime(startTime, "getContentProviderImpl: after appDied");
10184                        if (!lastRef) {
10185                            // This wasn't the last ref our process had on
10186                            // the provider...  we have now been killed, bail.
10187                            return null;
10188                        }
10189                        providerRunning = false;
10190                        conn = null;
10191                    }
10192                }
10193
10194                Binder.restoreCallingIdentity(origId);
10195            }
10196
10197            if (!providerRunning) {
10198                try {
10199                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10200                    cpi = AppGlobals.getPackageManager().
10201                        resolveContentProvider(name,
10202                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10203                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10204                } catch (RemoteException ex) {
10205                }
10206                if (cpi == null) {
10207                    return null;
10208                }
10209                // If the provider is a singleton AND
10210                // (it's a call within the same user || the provider is a
10211                // privileged app)
10212                // Then allow connecting to the singleton provider
10213                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10214                        cpi.name, cpi.flags)
10215                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10216                if (singleton) {
10217                    userId = UserHandle.USER_SYSTEM;
10218                }
10219                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10220                checkTime(startTime, "getContentProviderImpl: got app info for user");
10221
10222                String msg;
10223                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10224                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10225                        != null) {
10226                    throw new SecurityException(msg);
10227                }
10228                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10229
10230                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10231                        && !cpi.processName.equals("system")) {
10232                    // If this content provider does not run in the system
10233                    // process, and the system is not yet ready to run other
10234                    // processes, then fail fast instead of hanging.
10235                    throw new IllegalArgumentException(
10236                            "Attempt to launch content provider before system ready");
10237                }
10238
10239                // Make sure that the user who owns this provider is running.  If not,
10240                // we don't want to allow it to run.
10241                if (!mUserController.isUserRunningLocked(userId, 0)) {
10242                    Slog.w(TAG, "Unable to launch app "
10243                            + cpi.applicationInfo.packageName + "/"
10244                            + cpi.applicationInfo.uid + " for provider "
10245                            + name + ": user " + userId + " is stopped");
10246                    return null;
10247                }
10248
10249                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10250                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10251                cpr = mProviderMap.getProviderByClass(comp, userId);
10252                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10253                final boolean firstClass = cpr == null;
10254                if (firstClass) {
10255                    final long ident = Binder.clearCallingIdentity();
10256
10257                    // If permissions need a review before any of the app components can run,
10258                    // we return no provider and launch a review activity if the calling app
10259                    // is in the foreground.
10260                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10261                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10262                            return null;
10263                        }
10264                    }
10265
10266                    try {
10267                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10268                        ApplicationInfo ai =
10269                            AppGlobals.getPackageManager().
10270                                getApplicationInfo(
10271                                        cpi.applicationInfo.packageName,
10272                                        STOCK_PM_FLAGS, userId);
10273                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10274                        if (ai == null) {
10275                            Slog.w(TAG, "No package info for content provider "
10276                                    + cpi.name);
10277                            return null;
10278                        }
10279                        ai = getAppInfoForUser(ai, userId);
10280                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10281                    } catch (RemoteException ex) {
10282                        // pm is in same process, this will never happen.
10283                    } finally {
10284                        Binder.restoreCallingIdentity(ident);
10285                    }
10286                }
10287
10288                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10289
10290                if (r != null && cpr.canRunHere(r)) {
10291                    // If this is a multiprocess provider, then just return its
10292                    // info and allow the caller to instantiate it.  Only do
10293                    // this if the provider is the same user as the caller's
10294                    // process, or can run as root (so can be in any process).
10295                    return cpr.newHolder(null);
10296                }
10297
10298                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10299                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10300                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10301
10302                // This is single process, and our app is now connecting to it.
10303                // See if we are already in the process of launching this
10304                // provider.
10305                final int N = mLaunchingProviders.size();
10306                int i;
10307                for (i = 0; i < N; i++) {
10308                    if (mLaunchingProviders.get(i) == cpr) {
10309                        break;
10310                    }
10311                }
10312
10313                // If the provider is not already being launched, then get it
10314                // started.
10315                if (i >= N) {
10316                    final long origId = Binder.clearCallingIdentity();
10317
10318                    try {
10319                        // Content provider is now in use, its package can't be stopped.
10320                        try {
10321                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10322                            AppGlobals.getPackageManager().setPackageStoppedState(
10323                                    cpr.appInfo.packageName, false, userId);
10324                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10325                        } catch (RemoteException e) {
10326                        } catch (IllegalArgumentException e) {
10327                            Slog.w(TAG, "Failed trying to unstop package "
10328                                    + cpr.appInfo.packageName + ": " + e);
10329                        }
10330
10331                        // Use existing process if already started
10332                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10333                        ProcessRecord proc = getProcessRecordLocked(
10334                                cpi.processName, cpr.appInfo.uid, false);
10335                        if (proc != null && proc.thread != null) {
10336                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10337                                    "Installing in existing process " + proc);
10338                            if (!proc.pubProviders.containsKey(cpi.name)) {
10339                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10340                                proc.pubProviders.put(cpi.name, cpr);
10341                                try {
10342                                    proc.thread.scheduleInstallProvider(cpi);
10343                                } catch (RemoteException e) {
10344                                }
10345                            }
10346                        } else {
10347                            checkTime(startTime, "getContentProviderImpl: before start process");
10348                            proc = startProcessLocked(cpi.processName,
10349                                    cpr.appInfo, false, 0, "content provider",
10350                                    new ComponentName(cpi.applicationInfo.packageName,
10351                                            cpi.name), false, false, false);
10352                            checkTime(startTime, "getContentProviderImpl: after start process");
10353                            if (proc == null) {
10354                                Slog.w(TAG, "Unable to launch app "
10355                                        + cpi.applicationInfo.packageName + "/"
10356                                        + cpi.applicationInfo.uid + " for provider "
10357                                        + name + ": process is bad");
10358                                return null;
10359                            }
10360                        }
10361                        cpr.launchingApp = proc;
10362                        mLaunchingProviders.add(cpr);
10363                    } finally {
10364                        Binder.restoreCallingIdentity(origId);
10365                    }
10366                }
10367
10368                checkTime(startTime, "getContentProviderImpl: updating data structures");
10369
10370                // Make sure the provider is published (the same provider class
10371                // may be published under multiple names).
10372                if (firstClass) {
10373                    mProviderMap.putProviderByClass(comp, cpr);
10374                }
10375
10376                mProviderMap.putProviderByName(name, cpr);
10377                conn = incProviderCountLocked(r, cpr, token, stable);
10378                if (conn != null) {
10379                    conn.waiting = true;
10380                }
10381            }
10382            checkTime(startTime, "getContentProviderImpl: done!");
10383        }
10384
10385        // Wait for the provider to be published...
10386        synchronized (cpr) {
10387            while (cpr.provider == null) {
10388                if (cpr.launchingApp == null) {
10389                    Slog.w(TAG, "Unable to launch app "
10390                            + cpi.applicationInfo.packageName + "/"
10391                            + cpi.applicationInfo.uid + " for provider "
10392                            + name + ": launching app became null");
10393                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10394                            UserHandle.getUserId(cpi.applicationInfo.uid),
10395                            cpi.applicationInfo.packageName,
10396                            cpi.applicationInfo.uid, name);
10397                    return null;
10398                }
10399                try {
10400                    if (DEBUG_MU) Slog.v(TAG_MU,
10401                            "Waiting to start provider " + cpr
10402                            + " launchingApp=" + cpr.launchingApp);
10403                    if (conn != null) {
10404                        conn.waiting = true;
10405                    }
10406                    cpr.wait();
10407                } catch (InterruptedException ex) {
10408                } finally {
10409                    if (conn != null) {
10410                        conn.waiting = false;
10411                    }
10412                }
10413            }
10414        }
10415        return cpr != null ? cpr.newHolder(conn) : null;
10416    }
10417
10418    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10419            ProcessRecord r, final int userId) {
10420        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10421                cpi.packageName, r.userId)) {
10422
10423            final boolean callerForeground = r != null ? r.setSchedGroup
10424                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10425
10426            // Show a permission review UI only for starting from a foreground app
10427            if (!callerForeground) {
10428                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10429                        + cpi.packageName + " requires a permissions review");
10430                return false;
10431            }
10432
10433            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10434            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10435                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10436            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10437
10438            if (DEBUG_PERMISSIONS_REVIEW) {
10439                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10440                        + "for package " + cpi.packageName);
10441            }
10442
10443            final UserHandle userHandle = new UserHandle(userId);
10444            mHandler.post(new Runnable() {
10445                @Override
10446                public void run() {
10447                    mContext.startActivityAsUser(intent, userHandle);
10448                }
10449            });
10450
10451            return false;
10452        }
10453
10454        return true;
10455    }
10456
10457    PackageManagerInternal getPackageManagerInternalLocked() {
10458        if (mPackageManagerInt == null) {
10459            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10460        }
10461        return mPackageManagerInt;
10462    }
10463
10464    @Override
10465    public final ContentProviderHolder getContentProvider(
10466            IApplicationThread caller, String name, int userId, boolean stable) {
10467        enforceNotIsolatedCaller("getContentProvider");
10468        if (caller == null) {
10469            String msg = "null IApplicationThread when getting content provider "
10470                    + name;
10471            Slog.w(TAG, msg);
10472            throw new SecurityException(msg);
10473        }
10474        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10475        // with cross-user grant.
10476        return getContentProviderImpl(caller, name, null, stable, userId);
10477    }
10478
10479    public ContentProviderHolder getContentProviderExternal(
10480            String name, int userId, IBinder token) {
10481        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10482            "Do not have permission in call getContentProviderExternal()");
10483        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10484                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10485        return getContentProviderExternalUnchecked(name, token, userId);
10486    }
10487
10488    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10489            IBinder token, int userId) {
10490        return getContentProviderImpl(null, name, token, true, userId);
10491    }
10492
10493    /**
10494     * Drop a content provider from a ProcessRecord's bookkeeping
10495     */
10496    public void removeContentProvider(IBinder connection, boolean stable) {
10497        enforceNotIsolatedCaller("removeContentProvider");
10498        long ident = Binder.clearCallingIdentity();
10499        try {
10500            synchronized (this) {
10501                ContentProviderConnection conn;
10502                try {
10503                    conn = (ContentProviderConnection)connection;
10504                } catch (ClassCastException e) {
10505                    String msg ="removeContentProvider: " + connection
10506                            + " not a ContentProviderConnection";
10507                    Slog.w(TAG, msg);
10508                    throw new IllegalArgumentException(msg);
10509                }
10510                if (conn == null) {
10511                    throw new NullPointerException("connection is null");
10512                }
10513                if (decProviderCountLocked(conn, null, null, stable)) {
10514                    updateOomAdjLocked();
10515                }
10516            }
10517        } finally {
10518            Binder.restoreCallingIdentity(ident);
10519        }
10520    }
10521
10522    public void removeContentProviderExternal(String name, IBinder token) {
10523        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10524            "Do not have permission in call removeContentProviderExternal()");
10525        int userId = UserHandle.getCallingUserId();
10526        long ident = Binder.clearCallingIdentity();
10527        try {
10528            removeContentProviderExternalUnchecked(name, token, userId);
10529        } finally {
10530            Binder.restoreCallingIdentity(ident);
10531        }
10532    }
10533
10534    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10535        synchronized (this) {
10536            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10537            if(cpr == null) {
10538                //remove from mProvidersByClass
10539                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10540                return;
10541            }
10542
10543            //update content provider record entry info
10544            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10545            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10546            if (localCpr.hasExternalProcessHandles()) {
10547                if (localCpr.removeExternalProcessHandleLocked(token)) {
10548                    updateOomAdjLocked();
10549                } else {
10550                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10551                            + " with no external reference for token: "
10552                            + token + ".");
10553                }
10554            } else {
10555                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10556                        + " with no external references.");
10557            }
10558        }
10559    }
10560
10561    public final void publishContentProviders(IApplicationThread caller,
10562            List<ContentProviderHolder> providers) {
10563        if (providers == null) {
10564            return;
10565        }
10566
10567        enforceNotIsolatedCaller("publishContentProviders");
10568        synchronized (this) {
10569            final ProcessRecord r = getRecordForAppLocked(caller);
10570            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10571            if (r == null) {
10572                throw new SecurityException(
10573                        "Unable to find app for caller " + caller
10574                      + " (pid=" + Binder.getCallingPid()
10575                      + ") when publishing content providers");
10576            }
10577
10578            final long origId = Binder.clearCallingIdentity();
10579
10580            final int N = providers.size();
10581            for (int i = 0; i < N; i++) {
10582                ContentProviderHolder src = providers.get(i);
10583                if (src == null || src.info == null || src.provider == null) {
10584                    continue;
10585                }
10586                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10587                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10588                if (dst != null) {
10589                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10590                    mProviderMap.putProviderByClass(comp, dst);
10591                    String names[] = dst.info.authority.split(";");
10592                    for (int j = 0; j < names.length; j++) {
10593                        mProviderMap.putProviderByName(names[j], dst);
10594                    }
10595
10596                    int launchingCount = mLaunchingProviders.size();
10597                    int j;
10598                    boolean wasInLaunchingProviders = false;
10599                    for (j = 0; j < launchingCount; j++) {
10600                        if (mLaunchingProviders.get(j) == dst) {
10601                            mLaunchingProviders.remove(j);
10602                            wasInLaunchingProviders = true;
10603                            j--;
10604                            launchingCount--;
10605                        }
10606                    }
10607                    if (wasInLaunchingProviders) {
10608                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10609                    }
10610                    synchronized (dst) {
10611                        dst.provider = src.provider;
10612                        dst.proc = r;
10613                        dst.notifyAll();
10614                    }
10615                    updateOomAdjLocked(r);
10616                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10617                            src.info.authority);
10618                }
10619            }
10620
10621            Binder.restoreCallingIdentity(origId);
10622        }
10623    }
10624
10625    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10626        ContentProviderConnection conn;
10627        try {
10628            conn = (ContentProviderConnection)connection;
10629        } catch (ClassCastException e) {
10630            String msg ="refContentProvider: " + connection
10631                    + " not a ContentProviderConnection";
10632            Slog.w(TAG, msg);
10633            throw new IllegalArgumentException(msg);
10634        }
10635        if (conn == null) {
10636            throw new NullPointerException("connection is null");
10637        }
10638
10639        synchronized (this) {
10640            if (stable > 0) {
10641                conn.numStableIncs += stable;
10642            }
10643            stable = conn.stableCount + stable;
10644            if (stable < 0) {
10645                throw new IllegalStateException("stableCount < 0: " + stable);
10646            }
10647
10648            if (unstable > 0) {
10649                conn.numUnstableIncs += unstable;
10650            }
10651            unstable = conn.unstableCount + unstable;
10652            if (unstable < 0) {
10653                throw new IllegalStateException("unstableCount < 0: " + unstable);
10654            }
10655
10656            if ((stable+unstable) <= 0) {
10657                throw new IllegalStateException("ref counts can't go to zero here: stable="
10658                        + stable + " unstable=" + unstable);
10659            }
10660            conn.stableCount = stable;
10661            conn.unstableCount = unstable;
10662            return !conn.dead;
10663        }
10664    }
10665
10666    public void unstableProviderDied(IBinder connection) {
10667        ContentProviderConnection conn;
10668        try {
10669            conn = (ContentProviderConnection)connection;
10670        } catch (ClassCastException e) {
10671            String msg ="refContentProvider: " + connection
10672                    + " not a ContentProviderConnection";
10673            Slog.w(TAG, msg);
10674            throw new IllegalArgumentException(msg);
10675        }
10676        if (conn == null) {
10677            throw new NullPointerException("connection is null");
10678        }
10679
10680        // Safely retrieve the content provider associated with the connection.
10681        IContentProvider provider;
10682        synchronized (this) {
10683            provider = conn.provider.provider;
10684        }
10685
10686        if (provider == null) {
10687            // Um, yeah, we're way ahead of you.
10688            return;
10689        }
10690
10691        // Make sure the caller is being honest with us.
10692        if (provider.asBinder().pingBinder()) {
10693            // Er, no, still looks good to us.
10694            synchronized (this) {
10695                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10696                        + " says " + conn + " died, but we don't agree");
10697                return;
10698            }
10699        }
10700
10701        // Well look at that!  It's dead!
10702        synchronized (this) {
10703            if (conn.provider.provider != provider) {
10704                // But something changed...  good enough.
10705                return;
10706            }
10707
10708            ProcessRecord proc = conn.provider.proc;
10709            if (proc == null || proc.thread == null) {
10710                // Seems like the process is already cleaned up.
10711                return;
10712            }
10713
10714            // As far as we're concerned, this is just like receiving a
10715            // death notification...  just a bit prematurely.
10716            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10717                    + ") early provider death");
10718            final long ident = Binder.clearCallingIdentity();
10719            try {
10720                appDiedLocked(proc);
10721            } finally {
10722                Binder.restoreCallingIdentity(ident);
10723            }
10724        }
10725    }
10726
10727    @Override
10728    public void appNotRespondingViaProvider(IBinder connection) {
10729        enforceCallingPermission(
10730                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10731
10732        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10733        if (conn == null) {
10734            Slog.w(TAG, "ContentProviderConnection is null");
10735            return;
10736        }
10737
10738        final ProcessRecord host = conn.provider.proc;
10739        if (host == null) {
10740            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10741            return;
10742        }
10743
10744        final long token = Binder.clearCallingIdentity();
10745        try {
10746            mAppErrors.appNotResponding(host, null, null, false, "ContentProvider not responding");
10747        } finally {
10748            Binder.restoreCallingIdentity(token);
10749        }
10750    }
10751
10752    public final void installSystemProviders() {
10753        List<ProviderInfo> providers;
10754        synchronized (this) {
10755            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10756            providers = generateApplicationProvidersLocked(app);
10757            if (providers != null) {
10758                for (int i=providers.size()-1; i>=0; i--) {
10759                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10760                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10761                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10762                                + ": not system .apk");
10763                        providers.remove(i);
10764                    }
10765                }
10766            }
10767        }
10768        if (providers != null) {
10769            mSystemThread.installSystemProviders(providers);
10770        }
10771
10772        mCoreSettingsObserver = new CoreSettingsObserver(this);
10773        mFontScaleSettingObserver = new FontScaleSettingObserver();
10774
10775        //mUsageStatsService.monitorPackages();
10776    }
10777
10778    /**
10779     * When a user is unlocked, we need to install encryption-unaware providers
10780     * belonging to any running apps.
10781     */
10782    private void installEncryptionUnawareProviders(int userId) {
10783        if (!StorageManager.isFileBasedEncryptionEnabled()) {
10784            // TODO: eventually pivot this back to look at current user state,
10785            // similar to the comment in UserManager.isUserUnlocked(), but for
10786            // now, if we started apps when "unlocked" then unaware providers
10787            // have already been spun up.
10788            return;
10789        }
10790
10791        // We're only interested in providers that are encryption unaware, and
10792        // we don't care about uninstalled apps, since there's no way they're
10793        // running at this point.
10794        final int matchFlags = GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE
10795                | MATCH_DEBUG_TRIAGED_MISSING;
10796
10797        synchronized (this) {
10798            final int NP = mProcessNames.getMap().size();
10799            for (int ip = 0; ip < NP; ip++) {
10800                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10801                final int NA = apps.size();
10802                for (int ia = 0; ia < NA; ia++) {
10803                    final ProcessRecord app = apps.valueAt(ia);
10804                    if (app.userId != userId || app.thread == null) continue;
10805
10806                    final int NG = app.pkgList.size();
10807                    for (int ig = 0; ig < NG; ig++) {
10808                        try {
10809                            final String pkgName = app.pkgList.keyAt(ig);
10810                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10811                                    .getPackageInfo(pkgName, matchFlags, userId);
10812                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10813                                for (ProviderInfo provInfo : pkgInfo.providers) {
10814                                    Log.v(TAG, "Installing " + provInfo);
10815                                    app.thread.scheduleInstallProvider(provInfo);
10816                                }
10817                            }
10818                        } catch (RemoteException ignored) {
10819                        }
10820                    }
10821                }
10822            }
10823        }
10824    }
10825
10826    /**
10827     * Allows apps to retrieve the MIME type of a URI.
10828     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10829     * users, then it does not need permission to access the ContentProvider.
10830     * Either, it needs cross-user uri grants.
10831     *
10832     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10833     *
10834     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10835     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10836     */
10837    public String getProviderMimeType(Uri uri, int userId) {
10838        enforceNotIsolatedCaller("getProviderMimeType");
10839        final String name = uri.getAuthority();
10840        int callingUid = Binder.getCallingUid();
10841        int callingPid = Binder.getCallingPid();
10842        long ident = 0;
10843        boolean clearedIdentity = false;
10844        synchronized (this) {
10845            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10846        }
10847        if (canClearIdentity(callingPid, callingUid, userId)) {
10848            clearedIdentity = true;
10849            ident = Binder.clearCallingIdentity();
10850        }
10851        ContentProviderHolder holder = null;
10852        try {
10853            holder = getContentProviderExternalUnchecked(name, null, userId);
10854            if (holder != null) {
10855                return holder.provider.getType(uri);
10856            }
10857        } catch (RemoteException e) {
10858            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10859            return null;
10860        } finally {
10861            // We need to clear the identity to call removeContentProviderExternalUnchecked
10862            if (!clearedIdentity) {
10863                ident = Binder.clearCallingIdentity();
10864            }
10865            try {
10866                if (holder != null) {
10867                    removeContentProviderExternalUnchecked(name, null, userId);
10868                }
10869            } finally {
10870                Binder.restoreCallingIdentity(ident);
10871            }
10872        }
10873
10874        return null;
10875    }
10876
10877    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10878        if (UserHandle.getUserId(callingUid) == userId) {
10879            return true;
10880        }
10881        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10882                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10883                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10884                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10885                return true;
10886        }
10887        return false;
10888    }
10889
10890    // =========================================================
10891    // GLOBAL MANAGEMENT
10892    // =========================================================
10893
10894    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10895            boolean isolated, int isolatedUid) {
10896        String proc = customProcess != null ? customProcess : info.processName;
10897        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10898        final int userId = UserHandle.getUserId(info.uid);
10899        int uid = info.uid;
10900        if (isolated) {
10901            if (isolatedUid == 0) {
10902                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10903                while (true) {
10904                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10905                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10906                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10907                    }
10908                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10909                    mNextIsolatedProcessUid++;
10910                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10911                        // No process for this uid, use it.
10912                        break;
10913                    }
10914                    stepsLeft--;
10915                    if (stepsLeft <= 0) {
10916                        return null;
10917                    }
10918                }
10919            } else {
10920                // Special case for startIsolatedProcess (internal only), where
10921                // the uid of the isolated process is specified by the caller.
10922                uid = isolatedUid;
10923            }
10924        }
10925        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10926        if (!mBooted && !mBooting
10927                && userId == UserHandle.USER_SYSTEM
10928                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10929            r.persistent = true;
10930        }
10931        addProcessNameLocked(r);
10932        return r;
10933    }
10934
10935    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10936            String abiOverride) {
10937        ProcessRecord app;
10938        if (!isolated) {
10939            app = getProcessRecordLocked(info.processName, info.uid, true);
10940        } else {
10941            app = null;
10942        }
10943
10944        if (app == null) {
10945            app = newProcessRecordLocked(info, null, isolated, 0);
10946            updateLruProcessLocked(app, false, null);
10947            updateOomAdjLocked();
10948        }
10949
10950        // This package really, really can not be stopped.
10951        try {
10952            AppGlobals.getPackageManager().setPackageStoppedState(
10953                    info.packageName, false, UserHandle.getUserId(app.uid));
10954        } catch (RemoteException e) {
10955        } catch (IllegalArgumentException e) {
10956            Slog.w(TAG, "Failed trying to unstop package "
10957                    + info.packageName + ": " + e);
10958        }
10959
10960        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10961            app.persistent = true;
10962            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10963        }
10964        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10965            mPersistentStartingProcesses.add(app);
10966            startProcessLocked(app, "added application", app.processName, abiOverride,
10967                    null /* entryPoint */, null /* entryPointArgs */);
10968        }
10969
10970        return app;
10971    }
10972
10973    public void unhandledBack() {
10974        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10975                "unhandledBack()");
10976
10977        synchronized(this) {
10978            final long origId = Binder.clearCallingIdentity();
10979            try {
10980                getFocusedStack().unhandledBackLocked();
10981            } finally {
10982                Binder.restoreCallingIdentity(origId);
10983            }
10984        }
10985    }
10986
10987    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10988        enforceNotIsolatedCaller("openContentUri");
10989        final int userId = UserHandle.getCallingUserId();
10990        String name = uri.getAuthority();
10991        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10992        ParcelFileDescriptor pfd = null;
10993        if (cph != null) {
10994            // We record the binder invoker's uid in thread-local storage before
10995            // going to the content provider to open the file.  Later, in the code
10996            // that handles all permissions checks, we look for this uid and use
10997            // that rather than the Activity Manager's own uid.  The effect is that
10998            // we do the check against the caller's permissions even though it looks
10999            // to the content provider like the Activity Manager itself is making
11000            // the request.
11001            Binder token = new Binder();
11002            sCallerIdentity.set(new Identity(
11003                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11004            try {
11005                pfd = cph.provider.openFile(null, uri, "r", null, token);
11006            } catch (FileNotFoundException e) {
11007                // do nothing; pfd will be returned null
11008            } finally {
11009                // Ensure that whatever happens, we clean up the identity state
11010                sCallerIdentity.remove();
11011                // Ensure we're done with the provider.
11012                removeContentProviderExternalUnchecked(name, null, userId);
11013            }
11014        } else {
11015            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11016        }
11017        return pfd;
11018    }
11019
11020    // Actually is sleeping or shutting down or whatever else in the future
11021    // is an inactive state.
11022    public boolean isSleepingOrShuttingDown() {
11023        return isSleeping() || mShuttingDown;
11024    }
11025
11026    public boolean isSleeping() {
11027        return mSleeping;
11028    }
11029
11030    void onWakefulnessChanged(int wakefulness) {
11031        synchronized(this) {
11032            mWakefulness = wakefulness;
11033            updateSleepIfNeededLocked();
11034        }
11035    }
11036
11037    void finishRunningVoiceLocked() {
11038        Slog.d(TAG, "finishRunningVoiceLocked()  >>>>");
11039        if (mRunningVoice != null) {
11040            mRunningVoice = null;
11041            mVoiceWakeLock.release();
11042            updateSleepIfNeededLocked();
11043        }
11044    }
11045
11046    void startTimeTrackingFocusedActivityLocked() {
11047        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11048            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11049        }
11050    }
11051
11052    void updateSleepIfNeededLocked() {
11053        if (mSleeping && !shouldSleepLocked()) {
11054            mSleeping = false;
11055            startTimeTrackingFocusedActivityLocked();
11056            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11057            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11058            updateOomAdjLocked();
11059        } else if (!mSleeping && shouldSleepLocked()) {
11060            mSleeping = true;
11061            if (mCurAppTimeTracker != null) {
11062                mCurAppTimeTracker.stop();
11063            }
11064            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11065            mStackSupervisor.goingToSleepLocked();
11066            updateOomAdjLocked();
11067
11068            // Initialize the wake times of all processes.
11069            checkExcessivePowerUsageLocked(false);
11070            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11071            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11072            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11073        }
11074    }
11075
11076    private boolean shouldSleepLocked() {
11077        // Resume applications while running a voice interactor.
11078        if (mRunningVoice != null) {
11079            return false;
11080        }
11081
11082        // TODO: Transform the lock screen state into a sleep token instead.
11083        switch (mWakefulness) {
11084            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11085            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11086            case PowerManagerInternal.WAKEFULNESS_DOZING:
11087                // Pause applications whenever the lock screen is shown or any sleep
11088                // tokens have been acquired.
11089                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11090            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11091            default:
11092                // If we're asleep then pause applications unconditionally.
11093                return true;
11094        }
11095    }
11096
11097    /** Pokes the task persister. */
11098    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11099        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11100    }
11101
11102    /** Notifies all listeners when the task stack has changed. */
11103    void notifyTaskStackChangedLocked() {
11104        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11105        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11106        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11107        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11108    }
11109
11110    /** Notifies all listeners when an Activity is pinned. */
11111    void notifyActivityPinnedLocked() {
11112        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11113        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11114    }
11115
11116    /**
11117     * Notifies all listeners when an attempt was made to start an an activity that is already
11118     * running in the pinned stack and the activity was not actually started, but the task is
11119     * either brought to the front or a new Intent is delivered to it.
11120     */
11121    void notifyPinnedActivityRestartAttemptLocked() {
11122        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11123        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11124    }
11125
11126    /** Notifies all listeners when the pinned stack animation ends. */
11127    @Override
11128    public void notifyPinnedStackAnimationEnded() {
11129        synchronized (this) {
11130            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11131            mHandler.obtainMessage(
11132                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11133        }
11134    }
11135
11136    @Override
11137    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11138        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11139    }
11140
11141    @Override
11142    public boolean shutdown(int timeout) {
11143        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11144                != PackageManager.PERMISSION_GRANTED) {
11145            throw new SecurityException("Requires permission "
11146                    + android.Manifest.permission.SHUTDOWN);
11147        }
11148
11149        boolean timedout = false;
11150
11151        synchronized(this) {
11152            mShuttingDown = true;
11153            updateEventDispatchingLocked();
11154            timedout = mStackSupervisor.shutdownLocked(timeout);
11155        }
11156
11157        mAppOpsService.shutdown();
11158        if (mUsageStatsService != null) {
11159            mUsageStatsService.prepareShutdown();
11160        }
11161        mBatteryStatsService.shutdown();
11162        synchronized (this) {
11163            mProcessStats.shutdownLocked();
11164            notifyTaskPersisterLocked(null, true);
11165        }
11166
11167        return timedout;
11168    }
11169
11170    public final void activitySlept(IBinder token) {
11171        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11172
11173        final long origId = Binder.clearCallingIdentity();
11174
11175        synchronized (this) {
11176            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11177            if (r != null) {
11178                mStackSupervisor.activitySleptLocked(r);
11179            }
11180        }
11181
11182        Binder.restoreCallingIdentity(origId);
11183    }
11184
11185    private String lockScreenShownToString() {
11186        switch (mLockScreenShown) {
11187            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11188            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11189            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11190            default: return "Unknown=" + mLockScreenShown;
11191        }
11192    }
11193
11194    void logLockScreen(String msg) {
11195        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11196                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11197                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11198                + " mSleeping=" + mSleeping);
11199    }
11200
11201    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11202        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11203        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11204        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11205            boolean wasRunningVoice = mRunningVoice != null;
11206            mRunningVoice = session;
11207            if (!wasRunningVoice) {
11208                mVoiceWakeLock.acquire();
11209                updateSleepIfNeededLocked();
11210            }
11211        }
11212    }
11213
11214    private void updateEventDispatchingLocked() {
11215        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11216    }
11217
11218    public void setLockScreenShown(boolean shown) {
11219        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11220                != PackageManager.PERMISSION_GRANTED) {
11221            throw new SecurityException("Requires permission "
11222                    + android.Manifest.permission.DEVICE_POWER);
11223        }
11224
11225        final int user = UserHandle.myUserId();
11226        synchronized(this) {
11227            long ident = Binder.clearCallingIdentity();
11228            try {
11229                if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
11230                    startHomeActivityLocked(user, "setLockScreenShown");
11231                }
11232                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11233                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11234                updateSleepIfNeededLocked();
11235            } finally {
11236                Binder.restoreCallingIdentity(ident);
11237            }
11238        }
11239    }
11240
11241    @Override
11242    public void stopAppSwitches() {
11243        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11244                != PackageManager.PERMISSION_GRANTED) {
11245            throw new SecurityException("viewquires permission "
11246                    + android.Manifest.permission.STOP_APP_SWITCHES);
11247        }
11248
11249        synchronized(this) {
11250            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11251                    + APP_SWITCH_DELAY_TIME;
11252            mDidAppSwitch = false;
11253            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11254            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11255            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11256        }
11257    }
11258
11259    public void resumeAppSwitches() {
11260        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11261                != PackageManager.PERMISSION_GRANTED) {
11262            throw new SecurityException("Requires permission "
11263                    + android.Manifest.permission.STOP_APP_SWITCHES);
11264        }
11265
11266        synchronized(this) {
11267            // Note that we don't execute any pending app switches... we will
11268            // let those wait until either the timeout, or the next start
11269            // activity request.
11270            mAppSwitchesAllowedTime = 0;
11271        }
11272    }
11273
11274    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11275            int callingPid, int callingUid, String name) {
11276        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11277            return true;
11278        }
11279
11280        int perm = checkComponentPermission(
11281                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11282                sourceUid, -1, true);
11283        if (perm == PackageManager.PERMISSION_GRANTED) {
11284            return true;
11285        }
11286
11287        // If the actual IPC caller is different from the logical source, then
11288        // also see if they are allowed to control app switches.
11289        if (callingUid != -1 && callingUid != sourceUid) {
11290            perm = checkComponentPermission(
11291                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11292                    callingUid, -1, true);
11293            if (perm == PackageManager.PERMISSION_GRANTED) {
11294                return true;
11295            }
11296        }
11297
11298        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11299        return false;
11300    }
11301
11302    public void setDebugApp(String packageName, boolean waitForDebugger,
11303            boolean persistent) {
11304        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11305                "setDebugApp()");
11306
11307        long ident = Binder.clearCallingIdentity();
11308        try {
11309            // Note that this is not really thread safe if there are multiple
11310            // callers into it at the same time, but that's not a situation we
11311            // care about.
11312            if (persistent) {
11313                final ContentResolver resolver = mContext.getContentResolver();
11314                Settings.Global.putString(
11315                    resolver, Settings.Global.DEBUG_APP,
11316                    packageName);
11317                Settings.Global.putInt(
11318                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11319                    waitForDebugger ? 1 : 0);
11320            }
11321
11322            synchronized (this) {
11323                if (!persistent) {
11324                    mOrigDebugApp = mDebugApp;
11325                    mOrigWaitForDebugger = mWaitForDebugger;
11326                }
11327                mDebugApp = packageName;
11328                mWaitForDebugger = waitForDebugger;
11329                mDebugTransient = !persistent;
11330                if (packageName != null) {
11331                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11332                            false, UserHandle.USER_ALL, "set debug app");
11333                }
11334            }
11335        } finally {
11336            Binder.restoreCallingIdentity(ident);
11337        }
11338    }
11339
11340    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11341        synchronized (this) {
11342            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11343            if (!isDebuggable) {
11344                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11345                    throw new SecurityException("Process not debuggable: " + app.packageName);
11346                }
11347            }
11348
11349            mTrackAllocationApp = processName;
11350        }
11351    }
11352
11353    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11354        synchronized (this) {
11355            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11356            if (!isDebuggable) {
11357                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11358                    throw new SecurityException("Process not debuggable: " + app.packageName);
11359                }
11360            }
11361            mProfileApp = processName;
11362            mProfileFile = profilerInfo.profileFile;
11363            if (mProfileFd != null) {
11364                try {
11365                    mProfileFd.close();
11366                } catch (IOException e) {
11367                }
11368                mProfileFd = null;
11369            }
11370            mProfileFd = profilerInfo.profileFd;
11371            mSamplingInterval = profilerInfo.samplingInterval;
11372            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11373            mProfileType = 0;
11374        }
11375    }
11376
11377    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11378        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11379        if (!isDebuggable) {
11380            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11381                throw new SecurityException("Process not debuggable: " + app.packageName);
11382            }
11383        }
11384        mNativeDebuggingApp = processName;
11385    }
11386
11387    @Override
11388    public void setAlwaysFinish(boolean enabled) {
11389        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11390                "setAlwaysFinish()");
11391
11392        long ident = Binder.clearCallingIdentity();
11393        try {
11394            Settings.Global.putInt(
11395                    mContext.getContentResolver(),
11396                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11397
11398            synchronized (this) {
11399                mAlwaysFinishActivities = enabled;
11400            }
11401        } finally {
11402            Binder.restoreCallingIdentity(ident);
11403        }
11404    }
11405
11406    @Override
11407    public void setLenientBackgroundCheck(boolean enabled) {
11408        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11409                "setLenientBackgroundCheck()");
11410
11411        long ident = Binder.clearCallingIdentity();
11412        try {
11413            Settings.Global.putInt(
11414                    mContext.getContentResolver(),
11415                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11416
11417            synchronized (this) {
11418                mLenientBackgroundCheck = enabled;
11419            }
11420        } finally {
11421            Binder.restoreCallingIdentity(ident);
11422        }
11423    }
11424
11425    @Override
11426    public void setActivityController(IActivityController controller) {
11427        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11428                "setActivityController()");
11429        synchronized (this) {
11430            mController = controller;
11431            Watchdog.getInstance().setActivityController(controller);
11432        }
11433    }
11434
11435    @Override
11436    public void setUserIsMonkey(boolean userIsMonkey) {
11437        synchronized (this) {
11438            synchronized (mPidsSelfLocked) {
11439                final int callingPid = Binder.getCallingPid();
11440                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11441                if (precessRecord == null) {
11442                    throw new SecurityException("Unknown process: " + callingPid);
11443                }
11444                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11445                    throw new SecurityException("Only an instrumentation process "
11446                            + "with a UiAutomation can call setUserIsMonkey");
11447                }
11448            }
11449            mUserIsMonkey = userIsMonkey;
11450        }
11451    }
11452
11453    @Override
11454    public boolean isUserAMonkey() {
11455        synchronized (this) {
11456            // If there is a controller also implies the user is a monkey.
11457            return (mUserIsMonkey || mController != null);
11458        }
11459    }
11460
11461    public void requestBugReport(int bugreportType) {
11462        String service = null;
11463        switch (bugreportType) {
11464            case ActivityManager.BUGREPORT_OPTION_FULL:
11465                service = "bugreport";
11466                break;
11467            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11468                service = "bugreportplus";
11469                break;
11470            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11471                service = "bugreportremote";
11472                break;
11473        }
11474        if (service == null) {
11475            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11476                    + bugreportType);
11477        }
11478        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11479        SystemProperties.set("ctl.start", service);
11480    }
11481
11482    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11483        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11484    }
11485
11486    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11487        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11488            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11489        }
11490        return KEY_DISPATCHING_TIMEOUT;
11491    }
11492
11493    @Override
11494    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11495        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11496                != PackageManager.PERMISSION_GRANTED) {
11497            throw new SecurityException("Requires permission "
11498                    + android.Manifest.permission.FILTER_EVENTS);
11499        }
11500        ProcessRecord proc;
11501        long timeout;
11502        synchronized (this) {
11503            synchronized (mPidsSelfLocked) {
11504                proc = mPidsSelfLocked.get(pid);
11505            }
11506            timeout = getInputDispatchingTimeoutLocked(proc);
11507        }
11508
11509        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11510            return -1;
11511        }
11512
11513        return timeout;
11514    }
11515
11516    /**
11517     * Handle input dispatching timeouts.
11518     * Returns whether input dispatching should be aborted or not.
11519     */
11520    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11521            final ActivityRecord activity, final ActivityRecord parent,
11522            final boolean aboveSystem, String reason) {
11523        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11524                != PackageManager.PERMISSION_GRANTED) {
11525            throw new SecurityException("Requires permission "
11526                    + android.Manifest.permission.FILTER_EVENTS);
11527        }
11528
11529        final String annotation;
11530        if (reason == null) {
11531            annotation = "Input dispatching timed out";
11532        } else {
11533            annotation = "Input dispatching timed out (" + reason + ")";
11534        }
11535
11536        if (proc != null) {
11537            synchronized (this) {
11538                if (proc.debugging) {
11539                    return false;
11540                }
11541
11542                if (mDidDexOpt) {
11543                    // Give more time since we were dexopting.
11544                    mDidDexOpt = false;
11545                    return false;
11546                }
11547
11548                if (proc.instrumentationClass != null) {
11549                    Bundle info = new Bundle();
11550                    info.putString("shortMsg", "keyDispatchingTimedOut");
11551                    info.putString("longMsg", annotation);
11552                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11553                    return true;
11554                }
11555            }
11556            mHandler.post(new Runnable() {
11557                @Override
11558                public void run() {
11559                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11560                }
11561            });
11562        }
11563
11564        return true;
11565    }
11566
11567    @Override
11568    public Bundle getAssistContextExtras(int requestType) {
11569        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11570                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11571        if (pae == null) {
11572            return null;
11573        }
11574        synchronized (pae) {
11575            while (!pae.haveResult) {
11576                try {
11577                    pae.wait();
11578                } catch (InterruptedException e) {
11579                }
11580            }
11581        }
11582        synchronized (this) {
11583            buildAssistBundleLocked(pae, pae.result);
11584            mPendingAssistExtras.remove(pae);
11585            mUiHandler.removeCallbacks(pae);
11586        }
11587        return pae.extras;
11588    }
11589
11590    @Override
11591    public boolean isAssistDataAllowedOnCurrentActivity() {
11592        int userId;
11593        synchronized (this) {
11594            userId = mUserController.getCurrentUserIdLocked();
11595            ActivityRecord activity = getFocusedStack().topActivity();
11596            if (activity == null) {
11597                return false;
11598            }
11599            userId = activity.userId;
11600        }
11601        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11602                Context.DEVICE_POLICY_SERVICE);
11603        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11604    }
11605
11606    @Override
11607    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11608        long ident = Binder.clearCallingIdentity();
11609        try {
11610            synchronized (this) {
11611                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11612                ActivityRecord top = getFocusedStack().topActivity();
11613                if (top != caller) {
11614                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11615                            + " is not current top " + top);
11616                    return false;
11617                }
11618                if (!top.nowVisible) {
11619                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11620                            + " is not visible");
11621                    return false;
11622                }
11623            }
11624            AssistUtils utils = new AssistUtils(mContext);
11625            return utils.showSessionForActiveService(args,
11626                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11627        } finally {
11628            Binder.restoreCallingIdentity(ident);
11629        }
11630    }
11631
11632    @Override
11633    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11634            IBinder activityToken) {
11635        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11636                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11637    }
11638
11639    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11640            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11641            long timeout) {
11642        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11643                "enqueueAssistContext()");
11644        synchronized (this) {
11645            ActivityRecord activity = getFocusedStack().topActivity();
11646            if (activity == null) {
11647                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11648                return null;
11649            }
11650            if (activity.app == null || activity.app.thread == null) {
11651                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11652                return null;
11653            }
11654            if (activityToken != null) {
11655                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11656                if (activity != caller) {
11657                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11658                            + " is not current top " + activity);
11659                    return null;
11660                }
11661            }
11662            PendingAssistExtras pae;
11663            Bundle extras = new Bundle();
11664            if (args != null) {
11665                extras.putAll(args);
11666            }
11667            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11668            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11669            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11670            try {
11671                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11672                        requestType);
11673                mPendingAssistExtras.add(pae);
11674                mUiHandler.postDelayed(pae, timeout);
11675            } catch (RemoteException e) {
11676                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11677                return null;
11678            }
11679            return pae;
11680        }
11681    }
11682
11683    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11684        IResultReceiver receiver;
11685        synchronized (this) {
11686            mPendingAssistExtras.remove(pae);
11687            receiver = pae.receiver;
11688        }
11689        if (receiver != null) {
11690            // Caller wants result sent back to them.
11691            try {
11692                pae.receiver.send(0, null);
11693            } catch (RemoteException e) {
11694            }
11695        }
11696    }
11697
11698    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11699        if (result != null) {
11700            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11701        }
11702        if (pae.hint != null) {
11703            pae.extras.putBoolean(pae.hint, true);
11704        }
11705    }
11706
11707    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11708            AssistContent content, Uri referrer) {
11709        PendingAssistExtras pae = (PendingAssistExtras)token;
11710        synchronized (pae) {
11711            pae.result = extras;
11712            pae.structure = structure;
11713            pae.content = content;
11714            if (referrer != null) {
11715                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11716            }
11717            pae.haveResult = true;
11718            pae.notifyAll();
11719            if (pae.intent == null && pae.receiver == null) {
11720                // Caller is just waiting for the result.
11721                return;
11722            }
11723        }
11724
11725        // We are now ready to launch the assist activity.
11726        IResultReceiver sendReceiver = null;
11727        Bundle sendBundle = null;
11728        synchronized (this) {
11729            buildAssistBundleLocked(pae, extras);
11730            boolean exists = mPendingAssistExtras.remove(pae);
11731            mUiHandler.removeCallbacks(pae);
11732            if (!exists) {
11733                // Timed out.
11734                return;
11735            }
11736            if ((sendReceiver=pae.receiver) != null) {
11737                // Caller wants result sent back to them.
11738                sendBundle = new Bundle();
11739                sendBundle.putBundle("data", pae.extras);
11740                sendBundle.putParcelable("structure", pae.structure);
11741                sendBundle.putParcelable("content", pae.content);
11742            }
11743        }
11744        if (sendReceiver != null) {
11745            try {
11746                sendReceiver.send(0, sendBundle);
11747            } catch (RemoteException e) {
11748            }
11749            return;
11750        }
11751
11752        long ident = Binder.clearCallingIdentity();
11753        try {
11754            pae.intent.replaceExtras(pae.extras);
11755            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11756                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11757                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11758            closeSystemDialogs("assist");
11759            try {
11760                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11761            } catch (ActivityNotFoundException e) {
11762                Slog.w(TAG, "No activity to handle assist action.", e);
11763            }
11764        } finally {
11765            Binder.restoreCallingIdentity(ident);
11766        }
11767    }
11768
11769    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11770            Bundle args) {
11771        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11772                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11773    }
11774
11775    public void registerProcessObserver(IProcessObserver observer) {
11776        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11777                "registerProcessObserver()");
11778        synchronized (this) {
11779            mProcessObservers.register(observer);
11780        }
11781    }
11782
11783    @Override
11784    public void unregisterProcessObserver(IProcessObserver observer) {
11785        synchronized (this) {
11786            mProcessObservers.unregister(observer);
11787        }
11788    }
11789
11790    @Override
11791    public void registerUidObserver(IUidObserver observer, int which) {
11792        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11793                "registerUidObserver()");
11794        synchronized (this) {
11795            mUidObservers.register(observer, which);
11796        }
11797    }
11798
11799    @Override
11800    public void unregisterUidObserver(IUidObserver observer) {
11801        synchronized (this) {
11802            mUidObservers.unregister(observer);
11803        }
11804    }
11805
11806    @Override
11807    public boolean convertFromTranslucent(IBinder token) {
11808        final long origId = Binder.clearCallingIdentity();
11809        try {
11810            synchronized (this) {
11811                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11812                if (r == null) {
11813                    return false;
11814                }
11815                final boolean translucentChanged = r.changeWindowTranslucency(true);
11816                if (translucentChanged) {
11817                    r.task.stack.releaseBackgroundResources(r);
11818                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11819                }
11820                mWindowManager.setAppFullscreen(token, true);
11821                return translucentChanged;
11822            }
11823        } finally {
11824            Binder.restoreCallingIdentity(origId);
11825        }
11826    }
11827
11828    @Override
11829    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11830        final long origId = Binder.clearCallingIdentity();
11831        try {
11832            synchronized (this) {
11833                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11834                if (r == null) {
11835                    return false;
11836                }
11837                int index = r.task.mActivities.lastIndexOf(r);
11838                if (index > 0) {
11839                    ActivityRecord under = r.task.mActivities.get(index - 1);
11840                    under.returningOptions = options;
11841                }
11842                final boolean translucentChanged = r.changeWindowTranslucency(false);
11843                if (translucentChanged) {
11844                    r.task.stack.convertActivityToTranslucent(r);
11845                }
11846                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11847                mWindowManager.setAppFullscreen(token, false);
11848                return translucentChanged;
11849            }
11850        } finally {
11851            Binder.restoreCallingIdentity(origId);
11852        }
11853    }
11854
11855    @Override
11856    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11857        final long origId = Binder.clearCallingIdentity();
11858        try {
11859            synchronized (this) {
11860                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11861                if (r != null) {
11862                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11863                }
11864            }
11865            return false;
11866        } finally {
11867            Binder.restoreCallingIdentity(origId);
11868        }
11869    }
11870
11871    @Override
11872    public boolean isBackgroundVisibleBehind(IBinder token) {
11873        final long origId = Binder.clearCallingIdentity();
11874        try {
11875            synchronized (this) {
11876                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11877                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11878                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11879                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11880                return visible;
11881            }
11882        } finally {
11883            Binder.restoreCallingIdentity(origId);
11884        }
11885    }
11886
11887    @Override
11888    public ActivityOptions getActivityOptions(IBinder token) {
11889        final long origId = Binder.clearCallingIdentity();
11890        try {
11891            synchronized (this) {
11892                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11893                if (r != null) {
11894                    final ActivityOptions activityOptions = r.pendingOptions;
11895                    r.pendingOptions = null;
11896                    return activityOptions;
11897                }
11898                return null;
11899            }
11900        } finally {
11901            Binder.restoreCallingIdentity(origId);
11902        }
11903    }
11904
11905    @Override
11906    public void setImmersive(IBinder token, boolean immersive) {
11907        synchronized(this) {
11908            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11909            if (r == null) {
11910                throw new IllegalArgumentException();
11911            }
11912            r.immersive = immersive;
11913
11914            // update associated state if we're frontmost
11915            if (r == mFocusedActivity) {
11916                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11917                applyUpdateLockStateLocked(r);
11918            }
11919        }
11920    }
11921
11922    @Override
11923    public boolean isImmersive(IBinder token) {
11924        synchronized (this) {
11925            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11926            if (r == null) {
11927                throw new IllegalArgumentException();
11928            }
11929            return r.immersive;
11930        }
11931    }
11932
11933    @Override
11934    public void setVrMode(IBinder token, boolean enabled) {
11935        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11936            throw new UnsupportedOperationException("VR mode not supported on this device!");
11937        }
11938
11939        synchronized(this) {
11940            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11941            if (r == null) {
11942                throw new IllegalArgumentException();
11943            }
11944            r.isVrActivity = enabled;
11945
11946            // Update associated state if this activity is currently focused
11947            if (r == mFocusedActivity) {
11948                applyUpdateVrModeLocked(r);
11949            }
11950        }
11951    }
11952
11953    public boolean isTopActivityImmersive() {
11954        enforceNotIsolatedCaller("startActivity");
11955        synchronized (this) {
11956            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11957            return (r != null) ? r.immersive : false;
11958        }
11959    }
11960
11961    @Override
11962    public boolean isTopOfTask(IBinder token) {
11963        synchronized (this) {
11964            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11965            if (r == null) {
11966                throw new IllegalArgumentException();
11967            }
11968            return r.task.getTopActivity() == r;
11969        }
11970    }
11971
11972    public final void enterSafeMode() {
11973        synchronized(this) {
11974            // It only makes sense to do this before the system is ready
11975            // and started launching other packages.
11976            if (!mSystemReady) {
11977                try {
11978                    AppGlobals.getPackageManager().enterSafeMode();
11979                } catch (RemoteException e) {
11980                }
11981            }
11982
11983            mSafeMode = true;
11984        }
11985    }
11986
11987    public final void showSafeModeOverlay() {
11988        View v = LayoutInflater.from(mContext).inflate(
11989                com.android.internal.R.layout.safe_mode, null);
11990        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11991        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11992        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11993        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11994        lp.gravity = Gravity.BOTTOM | Gravity.START;
11995        lp.format = v.getBackground().getOpacity();
11996        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11997                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11998        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11999        ((WindowManager)mContext.getSystemService(
12000                Context.WINDOW_SERVICE)).addView(v, lp);
12001    }
12002
12003    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12004        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12005            return;
12006        }
12007        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12008        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12009        synchronized (stats) {
12010            if (mBatteryStatsService.isOnBattery()) {
12011                mBatteryStatsService.enforceCallingPermission();
12012                int MY_UID = Binder.getCallingUid();
12013                final int uid;
12014                if (sender == null) {
12015                    uid = sourceUid;
12016                } else {
12017                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12018                }
12019                BatteryStatsImpl.Uid.Pkg pkg =
12020                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12021                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12022                pkg.noteWakeupAlarmLocked(tag);
12023            }
12024        }
12025    }
12026
12027    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12028        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12029            return;
12030        }
12031        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12032        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12033        synchronized (stats) {
12034            mBatteryStatsService.enforceCallingPermission();
12035            int MY_UID = Binder.getCallingUid();
12036            final int uid;
12037            if (sender == null) {
12038                uid = sourceUid;
12039            } else {
12040                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12041            }
12042            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12043        }
12044    }
12045
12046    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12047        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12048            return;
12049        }
12050        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12051        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12052        synchronized (stats) {
12053            mBatteryStatsService.enforceCallingPermission();
12054            int MY_UID = Binder.getCallingUid();
12055            final int uid;
12056            if (sender == null) {
12057                uid = sourceUid;
12058            } else {
12059                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12060            }
12061            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12062        }
12063    }
12064
12065    public boolean killPids(int[] pids, String pReason, boolean secure) {
12066        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12067            throw new SecurityException("killPids only available to the system");
12068        }
12069        String reason = (pReason == null) ? "Unknown" : pReason;
12070        // XXX Note: don't acquire main activity lock here, because the window
12071        // manager calls in with its locks held.
12072
12073        boolean killed = false;
12074        synchronized (mPidsSelfLocked) {
12075            int worstType = 0;
12076            for (int i=0; i<pids.length; i++) {
12077                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12078                if (proc != null) {
12079                    int type = proc.setAdj;
12080                    if (type > worstType) {
12081                        worstType = type;
12082                    }
12083                }
12084            }
12085
12086            // If the worst oom_adj is somewhere in the cached proc LRU range,
12087            // then constrain it so we will kill all cached procs.
12088            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12089                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12090                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12091            }
12092
12093            // If this is not a secure call, don't let it kill processes that
12094            // are important.
12095            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12096                worstType = ProcessList.SERVICE_ADJ;
12097            }
12098
12099            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12100            for (int i=0; i<pids.length; i++) {
12101                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12102                if (proc == null) {
12103                    continue;
12104                }
12105                int adj = proc.setAdj;
12106                if (adj >= worstType && !proc.killedByAm) {
12107                    proc.kill(reason, true);
12108                    killed = true;
12109                }
12110            }
12111        }
12112        return killed;
12113    }
12114
12115    @Override
12116    public void killUid(int appId, int userId, String reason) {
12117        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12118        synchronized (this) {
12119            final long identity = Binder.clearCallingIdentity();
12120            try {
12121                killPackageProcessesLocked(null, appId, userId,
12122                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12123                        reason != null ? reason : "kill uid");
12124            } finally {
12125                Binder.restoreCallingIdentity(identity);
12126            }
12127        }
12128    }
12129
12130    @Override
12131    public boolean killProcessesBelowForeground(String reason) {
12132        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12133            throw new SecurityException("killProcessesBelowForeground() only available to system");
12134        }
12135
12136        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12137    }
12138
12139    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12140        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12141            throw new SecurityException("killProcessesBelowAdj() only available to system");
12142        }
12143
12144        boolean killed = false;
12145        synchronized (mPidsSelfLocked) {
12146            final int size = mPidsSelfLocked.size();
12147            for (int i = 0; i < size; i++) {
12148                final int pid = mPidsSelfLocked.keyAt(i);
12149                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12150                if (proc == null) continue;
12151
12152                final int adj = proc.setAdj;
12153                if (adj > belowAdj && !proc.killedByAm) {
12154                    proc.kill(reason, true);
12155                    killed = true;
12156                }
12157            }
12158        }
12159        return killed;
12160    }
12161
12162    @Override
12163    public void hang(final IBinder who, boolean allowRestart) {
12164        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12165                != PackageManager.PERMISSION_GRANTED) {
12166            throw new SecurityException("Requires permission "
12167                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12168        }
12169
12170        final IBinder.DeathRecipient death = new DeathRecipient() {
12171            @Override
12172            public void binderDied() {
12173                synchronized (this) {
12174                    notifyAll();
12175                }
12176            }
12177        };
12178
12179        try {
12180            who.linkToDeath(death, 0);
12181        } catch (RemoteException e) {
12182            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12183            return;
12184        }
12185
12186        synchronized (this) {
12187            Watchdog.getInstance().setAllowRestart(allowRestart);
12188            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12189            synchronized (death) {
12190                while (who.isBinderAlive()) {
12191                    try {
12192                        death.wait();
12193                    } catch (InterruptedException e) {
12194                    }
12195                }
12196            }
12197            Watchdog.getInstance().setAllowRestart(true);
12198        }
12199    }
12200
12201    @Override
12202    public void restart() {
12203        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12204                != PackageManager.PERMISSION_GRANTED) {
12205            throw new SecurityException("Requires permission "
12206                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12207        }
12208
12209        Log.i(TAG, "Sending shutdown broadcast...");
12210
12211        BroadcastReceiver br = new BroadcastReceiver() {
12212            @Override public void onReceive(Context context, Intent intent) {
12213                // Now the broadcast is done, finish up the low-level shutdown.
12214                Log.i(TAG, "Shutting down activity manager...");
12215                shutdown(10000);
12216                Log.i(TAG, "Shutdown complete, restarting!");
12217                Process.killProcess(Process.myPid());
12218                System.exit(10);
12219            }
12220        };
12221
12222        // First send the high-level shut down broadcast.
12223        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12224        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12225        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12226        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12227        mContext.sendOrderedBroadcastAsUser(intent,
12228                UserHandle.ALL, null, br, mHandler, 0, null, null);
12229        */
12230        br.onReceive(mContext, intent);
12231    }
12232
12233    private long getLowRamTimeSinceIdle(long now) {
12234        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12235    }
12236
12237    @Override
12238    public void performIdleMaintenance() {
12239        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12240                != PackageManager.PERMISSION_GRANTED) {
12241            throw new SecurityException("Requires permission "
12242                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12243        }
12244
12245        synchronized (this) {
12246            final long now = SystemClock.uptimeMillis();
12247            final long timeSinceLastIdle = now - mLastIdleTime;
12248            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12249            mLastIdleTime = now;
12250            mLowRamTimeSinceLastIdle = 0;
12251            if (mLowRamStartTime != 0) {
12252                mLowRamStartTime = now;
12253            }
12254
12255            StringBuilder sb = new StringBuilder(128);
12256            sb.append("Idle maintenance over ");
12257            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12258            sb.append(" low RAM for ");
12259            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12260            Slog.i(TAG, sb.toString());
12261
12262            // If at least 1/3 of our time since the last idle period has been spent
12263            // with RAM low, then we want to kill processes.
12264            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12265
12266            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12267                ProcessRecord proc = mLruProcesses.get(i);
12268                if (proc.notCachedSinceIdle) {
12269                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12270                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12271                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12272                        if (doKilling && proc.initialIdlePss != 0
12273                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12274                            sb = new StringBuilder(128);
12275                            sb.append("Kill");
12276                            sb.append(proc.processName);
12277                            sb.append(" in idle maint: pss=");
12278                            sb.append(proc.lastPss);
12279                            sb.append(", swapPss=");
12280                            sb.append(proc.lastSwapPss);
12281                            sb.append(", initialPss=");
12282                            sb.append(proc.initialIdlePss);
12283                            sb.append(", period=");
12284                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12285                            sb.append(", lowRamPeriod=");
12286                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12287                            Slog.wtfQuiet(TAG, sb.toString());
12288                            proc.kill("idle maint (pss " + proc.lastPss
12289                                    + " from " + proc.initialIdlePss + ")", true);
12290                        }
12291                    }
12292                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12293                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12294                    proc.notCachedSinceIdle = true;
12295                    proc.initialIdlePss = 0;
12296                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12297                            mTestPssMode, isSleeping(), now);
12298                }
12299            }
12300
12301            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12302            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12303        }
12304    }
12305
12306    private void retrieveSettings() {
12307        final ContentResolver resolver = mContext.getContentResolver();
12308        final boolean freeformWindowManagement =
12309                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12310                        || Settings.Global.getInt(
12311                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12312        final boolean supportsPictureInPicture =
12313                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12314
12315        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12316        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12317        final boolean alwaysFinishActivities =
12318                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12319        final boolean lenientBackgroundCheck =
12320                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12321        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12322        final boolean forceResizable = Settings.Global.getInt(
12323                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12324        // Transfer any global setting for forcing RTL layout, into a System Property
12325        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12326
12327        final Configuration configuration = new Configuration();
12328        Settings.System.getConfiguration(resolver, configuration);
12329        if (forceRtl) {
12330            // This will take care of setting the correct layout direction flags
12331            configuration.setLayoutDirection(configuration.locale);
12332        }
12333
12334        synchronized (this) {
12335            mDebugApp = mOrigDebugApp = debugApp;
12336            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12337            mAlwaysFinishActivities = alwaysFinishActivities;
12338            mLenientBackgroundCheck = lenientBackgroundCheck;
12339            mForceResizableActivities = forceResizable;
12340            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12341            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12342            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12343            // This happens before any activities are started, so we can
12344            // change mConfiguration in-place.
12345            updateConfigurationLocked(configuration, null, true);
12346            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12347                    "Initial config: " + mConfiguration);
12348
12349            // Load resources only after the current configuration has been set.
12350            final Resources res = mContext.getResources();
12351            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12352            mThumbnailWidth = res.getDimensionPixelSize(
12353                    com.android.internal.R.dimen.thumbnail_width);
12354            mThumbnailHeight = res.getDimensionPixelSize(
12355                    com.android.internal.R.dimen.thumbnail_height);
12356            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12357                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12358            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12359                    com.android.internal.R.string.config_appsNotReportingCrashes));
12360        }
12361    }
12362
12363    public boolean testIsSystemReady() {
12364        // no need to synchronize(this) just to read & return the value
12365        return mSystemReady;
12366    }
12367
12368    private static File getCalledPreBootReceiversFile() {
12369        File dataDir = Environment.getDataDirectory();
12370        File systemDir = new File(dataDir, "system");
12371        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12372        return fname;
12373    }
12374
12375    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12376        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12377        File file = getCalledPreBootReceiversFile();
12378        FileInputStream fis = null;
12379        try {
12380            fis = new FileInputStream(file);
12381            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12382            int fvers = dis.readInt();
12383            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12384                String vers = dis.readUTF();
12385                String codename = dis.readUTF();
12386                String build = dis.readUTF();
12387                if (android.os.Build.VERSION.RELEASE.equals(vers)
12388                        && android.os.Build.VERSION.CODENAME.equals(codename)
12389                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12390                    int num = dis.readInt();
12391                    while (num > 0) {
12392                        num--;
12393                        String pkg = dis.readUTF();
12394                        String cls = dis.readUTF();
12395                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12396                    }
12397                }
12398            }
12399        } catch (FileNotFoundException e) {
12400        } catch (IOException e) {
12401            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12402        } finally {
12403            if (fis != null) {
12404                try {
12405                    fis.close();
12406                } catch (IOException e) {
12407                }
12408            }
12409        }
12410        return lastDoneReceivers;
12411    }
12412
12413    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12414        File file = getCalledPreBootReceiversFile();
12415        FileOutputStream fos = null;
12416        DataOutputStream dos = null;
12417        try {
12418            fos = new FileOutputStream(file);
12419            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12420            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12421            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12422            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12423            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12424            dos.writeInt(list.size());
12425            for (int i=0; i<list.size(); i++) {
12426                dos.writeUTF(list.get(i).getPackageName());
12427                dos.writeUTF(list.get(i).getClassName());
12428            }
12429        } catch (IOException e) {
12430            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12431            file.delete();
12432        } finally {
12433            FileUtils.sync(fos);
12434            if (dos != null) {
12435                try {
12436                    dos.close();
12437                } catch (IOException e) {
12438                    // TODO Auto-generated catch block
12439                    e.printStackTrace();
12440                }
12441            }
12442        }
12443    }
12444
12445    final class PreBootContinuation extends IIntentReceiver.Stub {
12446        final Intent intent;
12447        final Runnable onFinishCallback;
12448        final ArrayList<ComponentName> doneReceivers;
12449        final List<ResolveInfo> ris;
12450        final int[] users;
12451        int lastRi = -1;
12452        int curRi = 0;
12453        int curUser = 0;
12454
12455        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12456                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12457            intent = _intent;
12458            onFinishCallback = _onFinishCallback;
12459            doneReceivers = _doneReceivers;
12460            ris = _ris;
12461            users = _users;
12462        }
12463
12464        void go() {
12465            if (lastRi != curRi) {
12466                ActivityInfo ai = ris.get(curRi).activityInfo;
12467                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12468                intent.setComponent(comp);
12469                doneReceivers.add(comp);
12470                lastRi = curRi;
12471                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12472                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12473            }
12474            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12475                    + " for user " + users[curUser]);
12476            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12477            broadcastIntentLocked(null, null, intent, null, this,
12478                    0, null, null, null, AppOpsManager.OP_NONE,
12479                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12480        }
12481
12482        public void performReceive(Intent intent, int resultCode,
12483                String data, Bundle extras, boolean ordered,
12484                boolean sticky, int sendingUser) {
12485            curUser++;
12486            if (curUser >= users.length) {
12487                curUser = 0;
12488                curRi++;
12489                if (curRi >= ris.size()) {
12490                    // All done sending broadcasts!
12491                    if (onFinishCallback != null) {
12492                        // The raw IIntentReceiver interface is called
12493                        // with the AM lock held, so redispatch to
12494                        // execute our code without the lock.
12495                        mHandler.post(onFinishCallback);
12496                    }
12497                    return;
12498                }
12499            }
12500            go();
12501        }
12502    }
12503
12504    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12505            ArrayList<ComponentName> doneReceivers) {
12506        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12507        List<ResolveInfo> ris = null;
12508        try {
12509            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12510                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
12511        } catch (RemoteException e) {
12512        }
12513        if (ris == null) {
12514            return false;
12515        }
12516        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12517
12518        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12519        for (int i=0; i<ris.size(); i++) {
12520            ActivityInfo ai = ris.get(i).activityInfo;
12521            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12522            if (lastDoneReceivers.contains(comp)) {
12523                // We already did the pre boot receiver for this app with the current
12524                // platform version, so don't do it again...
12525                ris.remove(i);
12526                i--;
12527                // ...however, do keep it as one that has been done, so we don't
12528                // forget about it when rewriting the file of last done receivers.
12529                doneReceivers.add(comp);
12530            }
12531        }
12532
12533        if (ris.size() <= 0) {
12534            return false;
12535        }
12536
12537        // TODO: can we still do this with per user encryption?
12538        final int[] users = mUserController.getUsers();
12539        if (users.length <= 0) {
12540            return false;
12541        }
12542
12543        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12544                ris, users);
12545        cont.go();
12546        return true;
12547    }
12548
12549    public void systemReady(final Runnable goingCallback) {
12550        synchronized(this) {
12551            if (mSystemReady) {
12552                // If we're done calling all the receivers, run the next "boot phase" passed in
12553                // by the SystemServer
12554                if (goingCallback != null) {
12555                    goingCallback.run();
12556                }
12557                return;
12558            }
12559
12560            mLocalDeviceIdleController
12561                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12562
12563            // Make sure we have the current profile info, since it is needed for security checks.
12564            mUserController.onSystemReady();
12565
12566            mRecentTasks.onSystemReadyLocked();
12567            // Check to see if there are any update receivers to run.
12568            if (!mDidUpdate) {
12569                if (mWaitingUpdate) {
12570                    return;
12571                }
12572                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12573                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12574                    public void run() {
12575                        synchronized (ActivityManagerService.this) {
12576                            mDidUpdate = true;
12577                        }
12578                        showBootMessage(mContext.getText(
12579                                R.string.android_upgrading_complete),
12580                                false);
12581                        writeLastDonePreBootReceivers(doneReceivers);
12582                        systemReady(goingCallback);
12583                    }
12584                }, doneReceivers);
12585
12586                if (mWaitingUpdate) {
12587                    return;
12588                }
12589                mDidUpdate = true;
12590            }
12591
12592            mAppOpsService.systemReady();
12593            mSystemReady = true;
12594        }
12595
12596        ArrayList<ProcessRecord> procsToKill = null;
12597        synchronized(mPidsSelfLocked) {
12598            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12599                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12600                if (!isAllowedWhileBooting(proc.info)){
12601                    if (procsToKill == null) {
12602                        procsToKill = new ArrayList<ProcessRecord>();
12603                    }
12604                    procsToKill.add(proc);
12605                }
12606            }
12607        }
12608
12609        synchronized(this) {
12610            if (procsToKill != null) {
12611                for (int i=procsToKill.size()-1; i>=0; i--) {
12612                    ProcessRecord proc = procsToKill.get(i);
12613                    Slog.i(TAG, "Removing system update proc: " + proc);
12614                    removeProcessLocked(proc, true, false, "system update done");
12615                }
12616            }
12617
12618            // Now that we have cleaned up any update processes, we
12619            // are ready to start launching real processes and know that
12620            // we won't trample on them any more.
12621            mProcessesReady = true;
12622        }
12623
12624        Slog.i(TAG, "System now ready");
12625        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12626            SystemClock.uptimeMillis());
12627
12628        synchronized(this) {
12629            // Make sure we have no pre-ready processes sitting around.
12630
12631            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12632                ResolveInfo ri = mContext.getPackageManager()
12633                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12634                                STOCK_PM_FLAGS);
12635                CharSequence errorMsg = null;
12636                if (ri != null) {
12637                    ActivityInfo ai = ri.activityInfo;
12638                    ApplicationInfo app = ai.applicationInfo;
12639                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12640                        mTopAction = Intent.ACTION_FACTORY_TEST;
12641                        mTopData = null;
12642                        mTopComponent = new ComponentName(app.packageName,
12643                                ai.name);
12644                    } else {
12645                        errorMsg = mContext.getResources().getText(
12646                                com.android.internal.R.string.factorytest_not_system);
12647                    }
12648                } else {
12649                    errorMsg = mContext.getResources().getText(
12650                            com.android.internal.R.string.factorytest_no_action);
12651                }
12652                if (errorMsg != null) {
12653                    mTopAction = null;
12654                    mTopData = null;
12655                    mTopComponent = null;
12656                    Message msg = Message.obtain();
12657                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12658                    msg.getData().putCharSequence("msg", errorMsg);
12659                    mUiHandler.sendMessage(msg);
12660                }
12661            }
12662        }
12663
12664        retrieveSettings();
12665        final int currentUserId;
12666        synchronized (this) {
12667            currentUserId = mUserController.getCurrentUserIdLocked();
12668            readGrantedUriPermissionsLocked();
12669        }
12670
12671        if (goingCallback != null) goingCallback.run();
12672
12673        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12674                Integer.toString(currentUserId), currentUserId);
12675        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12676                Integer.toString(currentUserId), currentUserId);
12677        mSystemServiceManager.startUser(currentUserId);
12678
12679        synchronized (this) {
12680            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12681                try {
12682                    List apps = AppGlobals.getPackageManager().
12683                        getPersistentApplications(STOCK_PM_FLAGS);
12684                    if (apps != null) {
12685                        int N = apps.size();
12686                        int i;
12687                        for (i=0; i<N; i++) {
12688                            ApplicationInfo info
12689                                = (ApplicationInfo)apps.get(i);
12690                            if (info != null &&
12691                                    !info.packageName.equals("android")) {
12692                                addAppLocked(info, false, null /* ABI override */);
12693                            }
12694                        }
12695                    }
12696                } catch (RemoteException ex) {
12697                    // pm is in same process, this will never happen.
12698                }
12699            }
12700
12701            // Start up initial activity.
12702            mBooting = true;
12703            // Enable home activity for system user, so that the system can always boot
12704            if (UserManager.isSplitSystemUser()) {
12705                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12706                try {
12707                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12708                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12709                            UserHandle.USER_SYSTEM);
12710                } catch (RemoteException e) {
12711                    throw e.rethrowAsRuntimeException();
12712                }
12713            }
12714            startHomeActivityLocked(currentUserId, "systemReady");
12715
12716            try {
12717                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12718                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12719                            + " data partition or your device will be unstable.");
12720                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12721                }
12722            } catch (RemoteException e) {
12723            }
12724
12725            if (!Build.isBuildConsistent()) {
12726                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12727                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12728            }
12729
12730            long ident = Binder.clearCallingIdentity();
12731            try {
12732                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12733                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12734                        | Intent.FLAG_RECEIVER_FOREGROUND);
12735                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12736                broadcastIntentLocked(null, null, intent,
12737                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12738                        null, false, false, MY_PID, Process.SYSTEM_UID,
12739                        currentUserId);
12740                intent = new Intent(Intent.ACTION_USER_STARTING);
12741                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12742                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12743                broadcastIntentLocked(null, null, intent,
12744                        null, new IIntentReceiver.Stub() {
12745                            @Override
12746                            public void performReceive(Intent intent, int resultCode, String data,
12747                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12748                                    throws RemoteException {
12749                            }
12750                        }, 0, null, null,
12751                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12752                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12753            } catch (Throwable t) {
12754                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12755            } finally {
12756                Binder.restoreCallingIdentity(ident);
12757            }
12758            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12759            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12760        }
12761    }
12762
12763    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12764        synchronized (this) {
12765            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12766        }
12767    }
12768
12769    void skipCurrentReceiverLocked(ProcessRecord app) {
12770        for (BroadcastQueue queue : mBroadcastQueues) {
12771            queue.skipCurrentReceiverLocked(app);
12772        }
12773    }
12774
12775    /**
12776     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12777     * The application process will exit immediately after this call returns.
12778     * @param app object of the crashing app, null for the system server
12779     * @param crashInfo describing the exception
12780     */
12781    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12782        ProcessRecord r = findAppProcess(app, "Crash");
12783        final String processName = app == null ? "system_server"
12784                : (r == null ? "unknown" : r.processName);
12785
12786        handleApplicationCrashInner("crash", r, processName, crashInfo);
12787    }
12788
12789    /* Native crash reporting uses this inner version because it needs to be somewhat
12790     * decoupled from the AM-managed cleanup lifecycle
12791     */
12792    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12793            ApplicationErrorReport.CrashInfo crashInfo) {
12794        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12795                UserHandle.getUserId(Binder.getCallingUid()), processName,
12796                r == null ? -1 : r.info.flags,
12797                crashInfo.exceptionClassName,
12798                crashInfo.exceptionMessage,
12799                crashInfo.throwFileName,
12800                crashInfo.throwLineNumber);
12801
12802        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12803
12804        mAppErrors.crashApplication(r, crashInfo);
12805    }
12806
12807    public void handleApplicationStrictModeViolation(
12808            IBinder app,
12809            int violationMask,
12810            StrictMode.ViolationInfo info) {
12811        ProcessRecord r = findAppProcess(app, "StrictMode");
12812        if (r == null) {
12813            return;
12814        }
12815
12816        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12817            Integer stackFingerprint = info.hashCode();
12818            boolean logIt = true;
12819            synchronized (mAlreadyLoggedViolatedStacks) {
12820                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12821                    logIt = false;
12822                    // TODO: sub-sample into EventLog for these, with
12823                    // the info.durationMillis?  Then we'd get
12824                    // the relative pain numbers, without logging all
12825                    // the stack traces repeatedly.  We'd want to do
12826                    // likewise in the client code, which also does
12827                    // dup suppression, before the Binder call.
12828                } else {
12829                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12830                        mAlreadyLoggedViolatedStacks.clear();
12831                    }
12832                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12833                }
12834            }
12835            if (logIt) {
12836                logStrictModeViolationToDropBox(r, info);
12837            }
12838        }
12839
12840        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12841            AppErrorResult result = new AppErrorResult();
12842            synchronized (this) {
12843                final long origId = Binder.clearCallingIdentity();
12844
12845                Message msg = Message.obtain();
12846                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12847                HashMap<String, Object> data = new HashMap<String, Object>();
12848                data.put("result", result);
12849                data.put("app", r);
12850                data.put("violationMask", violationMask);
12851                data.put("info", info);
12852                msg.obj = data;
12853                mUiHandler.sendMessage(msg);
12854
12855                Binder.restoreCallingIdentity(origId);
12856            }
12857            int res = result.get();
12858            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12859        }
12860    }
12861
12862    // Depending on the policy in effect, there could be a bunch of
12863    // these in quick succession so we try to batch these together to
12864    // minimize disk writes, number of dropbox entries, and maximize
12865    // compression, by having more fewer, larger records.
12866    private void logStrictModeViolationToDropBox(
12867            ProcessRecord process,
12868            StrictMode.ViolationInfo info) {
12869        if (info == null) {
12870            return;
12871        }
12872        final boolean isSystemApp = process == null ||
12873                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12874                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12875        final String processName = process == null ? "unknown" : process.processName;
12876        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12877        final DropBoxManager dbox = (DropBoxManager)
12878                mContext.getSystemService(Context.DROPBOX_SERVICE);
12879
12880        // Exit early if the dropbox isn't configured to accept this report type.
12881        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12882
12883        boolean bufferWasEmpty;
12884        boolean needsFlush;
12885        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12886        synchronized (sb) {
12887            bufferWasEmpty = sb.length() == 0;
12888            appendDropBoxProcessHeaders(process, processName, sb);
12889            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12890            sb.append("System-App: ").append(isSystemApp).append("\n");
12891            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12892            if (info.violationNumThisLoop != 0) {
12893                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12894            }
12895            if (info.numAnimationsRunning != 0) {
12896                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12897            }
12898            if (info.broadcastIntentAction != null) {
12899                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12900            }
12901            if (info.durationMillis != -1) {
12902                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12903            }
12904            if (info.numInstances != -1) {
12905                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12906            }
12907            if (info.tags != null) {
12908                for (String tag : info.tags) {
12909                    sb.append("Span-Tag: ").append(tag).append("\n");
12910                }
12911            }
12912            sb.append("\n");
12913            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12914                sb.append(info.crashInfo.stackTrace);
12915                sb.append("\n");
12916            }
12917            if (info.message != null) {
12918                sb.append(info.message);
12919                sb.append("\n");
12920            }
12921
12922            // Only buffer up to ~64k.  Various logging bits truncate
12923            // things at 128k.
12924            needsFlush = (sb.length() > 64 * 1024);
12925        }
12926
12927        // Flush immediately if the buffer's grown too large, or this
12928        // is a non-system app.  Non-system apps are isolated with a
12929        // different tag & policy and not batched.
12930        //
12931        // Batching is useful during internal testing with
12932        // StrictMode settings turned up high.  Without batching,
12933        // thousands of separate files could be created on boot.
12934        if (!isSystemApp || needsFlush) {
12935            new Thread("Error dump: " + dropboxTag) {
12936                @Override
12937                public void run() {
12938                    String report;
12939                    synchronized (sb) {
12940                        report = sb.toString();
12941                        sb.delete(0, sb.length());
12942                        sb.trimToSize();
12943                    }
12944                    if (report.length() != 0) {
12945                        dbox.addText(dropboxTag, report);
12946                    }
12947                }
12948            }.start();
12949            return;
12950        }
12951
12952        // System app batching:
12953        if (!bufferWasEmpty) {
12954            // An existing dropbox-writing thread is outstanding, so
12955            // we don't need to start it up.  The existing thread will
12956            // catch the buffer appends we just did.
12957            return;
12958        }
12959
12960        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12961        // (After this point, we shouldn't access AMS internal data structures.)
12962        new Thread("Error dump: " + dropboxTag) {
12963            @Override
12964            public void run() {
12965                // 5 second sleep to let stacks arrive and be batched together
12966                try {
12967                    Thread.sleep(5000);  // 5 seconds
12968                } catch (InterruptedException e) {}
12969
12970                String errorReport;
12971                synchronized (mStrictModeBuffer) {
12972                    errorReport = mStrictModeBuffer.toString();
12973                    if (errorReport.length() == 0) {
12974                        return;
12975                    }
12976                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12977                    mStrictModeBuffer.trimToSize();
12978                }
12979                dbox.addText(dropboxTag, errorReport);
12980            }
12981        }.start();
12982    }
12983
12984    /**
12985     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12986     * @param app object of the crashing app, null for the system server
12987     * @param tag reported by the caller
12988     * @param system whether this wtf is coming from the system
12989     * @param crashInfo describing the context of the error
12990     * @return true if the process should exit immediately (WTF is fatal)
12991     */
12992    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12993            final ApplicationErrorReport.CrashInfo crashInfo) {
12994        final int callingUid = Binder.getCallingUid();
12995        final int callingPid = Binder.getCallingPid();
12996
12997        if (system) {
12998            // If this is coming from the system, we could very well have low-level
12999            // system locks held, so we want to do this all asynchronously.  And we
13000            // never want this to become fatal, so there is that too.
13001            mHandler.post(new Runnable() {
13002                @Override public void run() {
13003                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13004                }
13005            });
13006            return false;
13007        }
13008
13009        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13010                crashInfo);
13011
13012        if (r != null && r.pid != Process.myPid() &&
13013                Settings.Global.getInt(mContext.getContentResolver(),
13014                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13015            mAppErrors.crashApplication(r, crashInfo);
13016            return true;
13017        } else {
13018            return false;
13019        }
13020    }
13021
13022    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13023            final ApplicationErrorReport.CrashInfo crashInfo) {
13024        final ProcessRecord r = findAppProcess(app, "WTF");
13025        final String processName = app == null ? "system_server"
13026                : (r == null ? "unknown" : r.processName);
13027
13028        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13029                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13030
13031        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13032
13033        return r;
13034    }
13035
13036    /**
13037     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13038     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13039     */
13040    private ProcessRecord findAppProcess(IBinder app, String reason) {
13041        if (app == null) {
13042            return null;
13043        }
13044
13045        synchronized (this) {
13046            final int NP = mProcessNames.getMap().size();
13047            for (int ip=0; ip<NP; ip++) {
13048                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13049                final int NA = apps.size();
13050                for (int ia=0; ia<NA; ia++) {
13051                    ProcessRecord p = apps.valueAt(ia);
13052                    if (p.thread != null && p.thread.asBinder() == app) {
13053                        return p;
13054                    }
13055                }
13056            }
13057
13058            Slog.w(TAG, "Can't find mystery application for " + reason
13059                    + " from pid=" + Binder.getCallingPid()
13060                    + " uid=" + Binder.getCallingUid() + ": " + app);
13061            return null;
13062        }
13063    }
13064
13065    /**
13066     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13067     * to append various headers to the dropbox log text.
13068     */
13069    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13070            StringBuilder sb) {
13071        // Watchdog thread ends up invoking this function (with
13072        // a null ProcessRecord) to add the stack file to dropbox.
13073        // Do not acquire a lock on this (am) in such cases, as it
13074        // could cause a potential deadlock, if and when watchdog
13075        // is invoked due to unavailability of lock on am and it
13076        // would prevent watchdog from killing system_server.
13077        if (process == null) {
13078            sb.append("Process: ").append(processName).append("\n");
13079            return;
13080        }
13081        // Note: ProcessRecord 'process' is guarded by the service
13082        // instance.  (notably process.pkgList, which could otherwise change
13083        // concurrently during execution of this method)
13084        synchronized (this) {
13085            sb.append("Process: ").append(processName).append("\n");
13086            int flags = process.info.flags;
13087            IPackageManager pm = AppGlobals.getPackageManager();
13088            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13089            for (int ip=0; ip<process.pkgList.size(); ip++) {
13090                String pkg = process.pkgList.keyAt(ip);
13091                sb.append("Package: ").append(pkg);
13092                try {
13093                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13094                    if (pi != null) {
13095                        sb.append(" v").append(pi.versionCode);
13096                        if (pi.versionName != null) {
13097                            sb.append(" (").append(pi.versionName).append(")");
13098                        }
13099                    }
13100                } catch (RemoteException e) {
13101                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13102                }
13103                sb.append("\n");
13104            }
13105        }
13106    }
13107
13108    private static String processClass(ProcessRecord process) {
13109        if (process == null || process.pid == MY_PID) {
13110            return "system_server";
13111        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13112            return "system_app";
13113        } else {
13114            return "data_app";
13115        }
13116    }
13117
13118    /**
13119     * Write a description of an error (crash, WTF, ANR) to the drop box.
13120     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13121     * @param process which caused the error, null means the system server
13122     * @param activity which triggered the error, null if unknown
13123     * @param parent activity related to the error, null if unknown
13124     * @param subject line related to the error, null if absent
13125     * @param report in long form describing the error, null if absent
13126     * @param logFile to include in the report, null if none
13127     * @param crashInfo giving an application stack trace, null if absent
13128     */
13129    public void addErrorToDropBox(String eventType,
13130            ProcessRecord process, String processName, ActivityRecord activity,
13131            ActivityRecord parent, String subject,
13132            final String report, final File logFile,
13133            final ApplicationErrorReport.CrashInfo crashInfo) {
13134        // NOTE -- this must never acquire the ActivityManagerService lock,
13135        // otherwise the watchdog may be prevented from resetting the system.
13136
13137        final String dropboxTag = processClass(process) + "_" + eventType;
13138        final DropBoxManager dbox = (DropBoxManager)
13139                mContext.getSystemService(Context.DROPBOX_SERVICE);
13140
13141        // Exit early if the dropbox isn't configured to accept this report type.
13142        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13143
13144        final StringBuilder sb = new StringBuilder(1024);
13145        appendDropBoxProcessHeaders(process, processName, sb);
13146        if (process != null) {
13147            sb.append("Foreground: ")
13148                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13149                    .append("\n");
13150        }
13151        if (activity != null) {
13152            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13153        }
13154        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13155            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13156        }
13157        if (parent != null && parent != activity) {
13158            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13159        }
13160        if (subject != null) {
13161            sb.append("Subject: ").append(subject).append("\n");
13162        }
13163        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13164        if (Debug.isDebuggerConnected()) {
13165            sb.append("Debugger: Connected\n");
13166        }
13167        sb.append("\n");
13168
13169        // Do the rest in a worker thread to avoid blocking the caller on I/O
13170        // (After this point, we shouldn't access AMS internal data structures.)
13171        Thread worker = new Thread("Error dump: " + dropboxTag) {
13172            @Override
13173            public void run() {
13174                if (report != null) {
13175                    sb.append(report);
13176                }
13177                if (logFile != null) {
13178                    try {
13179                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13180                                    "\n\n[[TRUNCATED]]"));
13181                    } catch (IOException e) {
13182                        Slog.e(TAG, "Error reading " + logFile, e);
13183                    }
13184                }
13185                if (crashInfo != null && crashInfo.stackTrace != null) {
13186                    sb.append(crashInfo.stackTrace);
13187                }
13188
13189                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13190                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13191                if (lines > 0) {
13192                    sb.append("\n");
13193
13194                    // Merge several logcat streams, and take the last N lines
13195                    InputStreamReader input = null;
13196                    try {
13197                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13198                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13199                                "-b", "crash",
13200                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13201
13202                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13203                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13204                        input = new InputStreamReader(logcat.getInputStream());
13205
13206                        int num;
13207                        char[] buf = new char[8192];
13208                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13209                    } catch (IOException e) {
13210                        Slog.e(TAG, "Error running logcat", e);
13211                    } finally {
13212                        if (input != null) try { input.close(); } catch (IOException e) {}
13213                    }
13214                }
13215
13216                dbox.addText(dropboxTag, sb.toString());
13217            }
13218        };
13219
13220        if (process == null) {
13221            // If process is null, we are being called from some internal code
13222            // and may be about to die -- run this synchronously.
13223            worker.run();
13224        } else {
13225            worker.start();
13226        }
13227    }
13228
13229    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13230        enforceNotIsolatedCaller("getProcessesInErrorState");
13231        // assume our apps are happy - lazy create the list
13232        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13233
13234        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13235                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13236        int userId = UserHandle.getUserId(Binder.getCallingUid());
13237
13238        synchronized (this) {
13239
13240            // iterate across all processes
13241            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13242                ProcessRecord app = mLruProcesses.get(i);
13243                if (!allUsers && app.userId != userId) {
13244                    continue;
13245                }
13246                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13247                    // This one's in trouble, so we'll generate a report for it
13248                    // crashes are higher priority (in case there's a crash *and* an anr)
13249                    ActivityManager.ProcessErrorStateInfo report = null;
13250                    if (app.crashing) {
13251                        report = app.crashingReport;
13252                    } else if (app.notResponding) {
13253                        report = app.notRespondingReport;
13254                    }
13255
13256                    if (report != null) {
13257                        if (errList == null) {
13258                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13259                        }
13260                        errList.add(report);
13261                    } else {
13262                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13263                                " crashing = " + app.crashing +
13264                                " notResponding = " + app.notResponding);
13265                    }
13266                }
13267            }
13268        }
13269
13270        return errList;
13271    }
13272
13273    static int procStateToImportance(int procState, int memAdj,
13274            ActivityManager.RunningAppProcessInfo currApp) {
13275        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13276        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13277            currApp.lru = memAdj;
13278        } else {
13279            currApp.lru = 0;
13280        }
13281        return imp;
13282    }
13283
13284    private void fillInProcMemInfo(ProcessRecord app,
13285            ActivityManager.RunningAppProcessInfo outInfo) {
13286        outInfo.pid = app.pid;
13287        outInfo.uid = app.info.uid;
13288        if (mHeavyWeightProcess == app) {
13289            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13290        }
13291        if (app.persistent) {
13292            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13293        }
13294        if (app.activities.size() > 0) {
13295            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13296        }
13297        outInfo.lastTrimLevel = app.trimMemoryLevel;
13298        int adj = app.curAdj;
13299        int procState = app.curProcState;
13300        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13301        outInfo.importanceReasonCode = app.adjTypeCode;
13302        outInfo.processState = app.curProcState;
13303    }
13304
13305    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13306        enforceNotIsolatedCaller("getRunningAppProcesses");
13307
13308        final int callingUid = Binder.getCallingUid();
13309
13310        // Lazy instantiation of list
13311        List<ActivityManager.RunningAppProcessInfo> runList = null;
13312        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13313                callingUid) == PackageManager.PERMISSION_GRANTED;
13314        final int userId = UserHandle.getUserId(callingUid);
13315        final boolean allUids = isGetTasksAllowed(
13316                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13317
13318        synchronized (this) {
13319            // Iterate across all processes
13320            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13321                ProcessRecord app = mLruProcesses.get(i);
13322                if ((!allUsers && app.userId != userId)
13323                        || (!allUids && app.uid != callingUid)) {
13324                    continue;
13325                }
13326                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13327                    // Generate process state info for running application
13328                    ActivityManager.RunningAppProcessInfo currApp =
13329                        new ActivityManager.RunningAppProcessInfo(app.processName,
13330                                app.pid, app.getPackageList());
13331                    fillInProcMemInfo(app, currApp);
13332                    if (app.adjSource instanceof ProcessRecord) {
13333                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13334                        currApp.importanceReasonImportance =
13335                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13336                                        app.adjSourceProcState);
13337                    } else if (app.adjSource instanceof ActivityRecord) {
13338                        ActivityRecord r = (ActivityRecord)app.adjSource;
13339                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13340                    }
13341                    if (app.adjTarget instanceof ComponentName) {
13342                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13343                    }
13344                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13345                    //        + " lru=" + currApp.lru);
13346                    if (runList == null) {
13347                        runList = new ArrayList<>();
13348                    }
13349                    runList.add(currApp);
13350                }
13351            }
13352        }
13353        return runList;
13354    }
13355
13356    public List<ApplicationInfo> getRunningExternalApplications() {
13357        enforceNotIsolatedCaller("getRunningExternalApplications");
13358        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13359        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13360        if (runningApps != null && runningApps.size() > 0) {
13361            Set<String> extList = new HashSet<String>();
13362            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13363                if (app.pkgList != null) {
13364                    for (String pkg : app.pkgList) {
13365                        extList.add(pkg);
13366                    }
13367                }
13368            }
13369            IPackageManager pm = AppGlobals.getPackageManager();
13370            for (String pkg : extList) {
13371                try {
13372                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13373                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13374                        retList.add(info);
13375                    }
13376                } catch (RemoteException e) {
13377                }
13378            }
13379        }
13380        return retList;
13381    }
13382
13383    @Override
13384    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13385        enforceNotIsolatedCaller("getMyMemoryState");
13386        synchronized (this) {
13387            ProcessRecord proc;
13388            synchronized (mPidsSelfLocked) {
13389                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13390            }
13391            fillInProcMemInfo(proc, outInfo);
13392        }
13393    }
13394
13395    @Override
13396    public int getMemoryTrimLevel() {
13397        enforceNotIsolatedCaller("getMyMemoryState");
13398        synchronized (this) {
13399            return mLastMemoryLevel;
13400        }
13401    }
13402
13403    @Override
13404    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13405            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13406        (new ActivityManagerShellCommand(this, false)).exec(
13407                this, in, out, err, args, resultReceiver);
13408    }
13409
13410    @Override
13411    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13412        if (checkCallingPermission(android.Manifest.permission.DUMP)
13413                != PackageManager.PERMISSION_GRANTED) {
13414            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13415                    + Binder.getCallingPid()
13416                    + ", uid=" + Binder.getCallingUid()
13417                    + " without permission "
13418                    + android.Manifest.permission.DUMP);
13419            return;
13420        }
13421
13422        boolean dumpAll = false;
13423        boolean dumpClient = false;
13424        String dumpPackage = null;
13425
13426        int opti = 0;
13427        while (opti < args.length) {
13428            String opt = args[opti];
13429            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13430                break;
13431            }
13432            opti++;
13433            if ("-a".equals(opt)) {
13434                dumpAll = true;
13435            } else if ("-c".equals(opt)) {
13436                dumpClient = true;
13437            } else if ("-p".equals(opt)) {
13438                if (opti < args.length) {
13439                    dumpPackage = args[opti];
13440                    opti++;
13441                } else {
13442                    pw.println("Error: -p option requires package argument");
13443                    return;
13444                }
13445                dumpClient = true;
13446            } else if ("-h".equals(opt)) {
13447                ActivityManagerShellCommand.dumpHelp(pw, true);
13448                return;
13449            } else {
13450                pw.println("Unknown argument: " + opt + "; use -h for help");
13451            }
13452        }
13453
13454        long origId = Binder.clearCallingIdentity();
13455        boolean more = false;
13456        // Is the caller requesting to dump a particular piece of data?
13457        if (opti < args.length) {
13458            String cmd = args[opti];
13459            opti++;
13460            if ("activities".equals(cmd) || "a".equals(cmd)) {
13461                synchronized (this) {
13462                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13463                }
13464            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13465                synchronized (this) {
13466                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13467                }
13468            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13469                String[] newArgs;
13470                String name;
13471                if (opti >= args.length) {
13472                    name = null;
13473                    newArgs = EMPTY_STRING_ARRAY;
13474                } else {
13475                    dumpPackage = args[opti];
13476                    opti++;
13477                    newArgs = new String[args.length - opti];
13478                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13479                            args.length - opti);
13480                }
13481                synchronized (this) {
13482                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13483                }
13484            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13485                String[] newArgs;
13486                String name;
13487                if (opti >= args.length) {
13488                    name = null;
13489                    newArgs = EMPTY_STRING_ARRAY;
13490                } else {
13491                    dumpPackage = args[opti];
13492                    opti++;
13493                    newArgs = new String[args.length - opti];
13494                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13495                            args.length - opti);
13496                }
13497                synchronized (this) {
13498                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13499                }
13500            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13501                String[] newArgs;
13502                String name;
13503                if (opti >= args.length) {
13504                    name = null;
13505                    newArgs = EMPTY_STRING_ARRAY;
13506                } else {
13507                    dumpPackage = args[opti];
13508                    opti++;
13509                    newArgs = new String[args.length - opti];
13510                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13511                            args.length - opti);
13512                }
13513                synchronized (this) {
13514                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13515                }
13516            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13517                synchronized (this) {
13518                    dumpOomLocked(fd, pw, args, opti, true);
13519                }
13520            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13521                synchronized (this) {
13522                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13523                }
13524            } else if ("provider".equals(cmd)) {
13525                String[] newArgs;
13526                String name;
13527                if (opti >= args.length) {
13528                    name = null;
13529                    newArgs = EMPTY_STRING_ARRAY;
13530                } else {
13531                    name = args[opti];
13532                    opti++;
13533                    newArgs = new String[args.length - opti];
13534                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13535                }
13536                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13537                    pw.println("No providers match: " + name);
13538                    pw.println("Use -h for help.");
13539                }
13540            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13541                synchronized (this) {
13542                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13543                }
13544            } else if ("service".equals(cmd)) {
13545                String[] newArgs;
13546                String name;
13547                if (opti >= args.length) {
13548                    name = null;
13549                    newArgs = EMPTY_STRING_ARRAY;
13550                } else {
13551                    name = args[opti];
13552                    opti++;
13553                    newArgs = new String[args.length - opti];
13554                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13555                            args.length - opti);
13556                }
13557                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13558                    pw.println("No services match: " + name);
13559                    pw.println("Use -h for help.");
13560                }
13561            } else if ("package".equals(cmd)) {
13562                String[] newArgs;
13563                if (opti >= args.length) {
13564                    pw.println("package: no package name specified");
13565                    pw.println("Use -h for help.");
13566                } else {
13567                    dumpPackage = args[opti];
13568                    opti++;
13569                    newArgs = new String[args.length - opti];
13570                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13571                            args.length - opti);
13572                    args = newArgs;
13573                    opti = 0;
13574                    more = true;
13575                }
13576            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13577                synchronized (this) {
13578                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13579                }
13580            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13581                synchronized (this) {
13582                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13583                }
13584            } else {
13585                // Dumping a single activity?
13586                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13587                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13588                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13589                    if (res < 0) {
13590                        pw.println("Bad activity command, or no activities match: " + cmd);
13591                        pw.println("Use -h for help.");
13592                    }
13593                }
13594            }
13595            if (!more) {
13596                Binder.restoreCallingIdentity(origId);
13597                return;
13598            }
13599        }
13600
13601        // No piece of data specified, dump everything.
13602        synchronized (this) {
13603            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13604            pw.println();
13605            if (dumpAll) {
13606                pw.println("-------------------------------------------------------------------------------");
13607            }
13608            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13609            pw.println();
13610            if (dumpAll) {
13611                pw.println("-------------------------------------------------------------------------------");
13612            }
13613            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13614            pw.println();
13615            if (dumpAll) {
13616                pw.println("-------------------------------------------------------------------------------");
13617            }
13618            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13619            pw.println();
13620            if (dumpAll) {
13621                pw.println("-------------------------------------------------------------------------------");
13622            }
13623            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13624            pw.println();
13625            if (dumpAll) {
13626                pw.println("-------------------------------------------------------------------------------");
13627            }
13628            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13629            pw.println();
13630            if (dumpAll) {
13631                pw.println("-------------------------------------------------------------------------------");
13632            }
13633            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13634            if (mAssociations.size() > 0) {
13635                pw.println();
13636                if (dumpAll) {
13637                    pw.println("-------------------------------------------------------------------------------");
13638                }
13639                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13640            }
13641            pw.println();
13642            if (dumpAll) {
13643                pw.println("-------------------------------------------------------------------------------");
13644            }
13645            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13646        }
13647        Binder.restoreCallingIdentity(origId);
13648    }
13649
13650    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13651            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13652        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13653
13654        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13655                dumpPackage);
13656        boolean needSep = printedAnything;
13657
13658        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13659                dumpPackage, needSep, "  mFocusedActivity: ");
13660        if (printed) {
13661            printedAnything = true;
13662            needSep = false;
13663        }
13664
13665        if (dumpPackage == null) {
13666            if (needSep) {
13667                pw.println();
13668            }
13669            needSep = true;
13670            printedAnything = true;
13671            mStackSupervisor.dump(pw, "  ");
13672        }
13673
13674        if (!printedAnything) {
13675            pw.println("  (nothing)");
13676        }
13677    }
13678
13679    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13680            int opti, boolean dumpAll, String dumpPackage) {
13681        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13682
13683        boolean printedAnything = false;
13684
13685        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13686            boolean printedHeader = false;
13687
13688            final int N = mRecentTasks.size();
13689            for (int i=0; i<N; i++) {
13690                TaskRecord tr = mRecentTasks.get(i);
13691                if (dumpPackage != null) {
13692                    if (tr.realActivity == null ||
13693                            !dumpPackage.equals(tr.realActivity)) {
13694                        continue;
13695                    }
13696                }
13697                if (!printedHeader) {
13698                    pw.println("  Recent tasks:");
13699                    printedHeader = true;
13700                    printedAnything = true;
13701                }
13702                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13703                        pw.println(tr);
13704                if (dumpAll) {
13705                    mRecentTasks.get(i).dump(pw, "    ");
13706                }
13707            }
13708        }
13709
13710        if (!printedAnything) {
13711            pw.println("  (nothing)");
13712        }
13713    }
13714
13715    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13716            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13717        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13718
13719        int dumpUid = 0;
13720        if (dumpPackage != null) {
13721            IPackageManager pm = AppGlobals.getPackageManager();
13722            try {
13723                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13724            } catch (RemoteException e) {
13725            }
13726        }
13727
13728        boolean printedAnything = false;
13729
13730        final long now = SystemClock.uptimeMillis();
13731
13732        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13733            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13734                    = mAssociations.valueAt(i1);
13735            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13736                SparseArray<ArrayMap<String, Association>> sourceUids
13737                        = targetComponents.valueAt(i2);
13738                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13739                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13740                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13741                        Association ass = sourceProcesses.valueAt(i4);
13742                        if (dumpPackage != null) {
13743                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13744                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13745                                continue;
13746                            }
13747                        }
13748                        printedAnything = true;
13749                        pw.print("  ");
13750                        pw.print(ass.mTargetProcess);
13751                        pw.print("/");
13752                        UserHandle.formatUid(pw, ass.mTargetUid);
13753                        pw.print(" <- ");
13754                        pw.print(ass.mSourceProcess);
13755                        pw.print("/");
13756                        UserHandle.formatUid(pw, ass.mSourceUid);
13757                        pw.println();
13758                        pw.print("    via ");
13759                        pw.print(ass.mTargetComponent.flattenToShortString());
13760                        pw.println();
13761                        pw.print("    ");
13762                        long dur = ass.mTime;
13763                        if (ass.mNesting > 0) {
13764                            dur += now - ass.mStartTime;
13765                        }
13766                        TimeUtils.formatDuration(dur, pw);
13767                        pw.print(" (");
13768                        pw.print(ass.mCount);
13769                        pw.println(" times)");
13770                        if (ass.mNesting > 0) {
13771                            pw.print("    ");
13772                            pw.print(" Currently active: ");
13773                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13774                            pw.println();
13775                        }
13776                    }
13777                }
13778            }
13779
13780        }
13781
13782        if (!printedAnything) {
13783            pw.println("  (nothing)");
13784        }
13785    }
13786
13787    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13788            String header, boolean needSep) {
13789        boolean printed = false;
13790        int whichAppId = -1;
13791        if (dumpPackage != null) {
13792            try {
13793                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13794                        dumpPackage, 0);
13795                whichAppId = UserHandle.getAppId(info.uid);
13796            } catch (NameNotFoundException e) {
13797                e.printStackTrace();
13798            }
13799        }
13800        for (int i=0; i<uids.size(); i++) {
13801            UidRecord uidRec = uids.valueAt(i);
13802            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13803                continue;
13804            }
13805            if (!printed) {
13806                printed = true;
13807                if (needSep) {
13808                    pw.println();
13809                }
13810                pw.print("  ");
13811                pw.println(header);
13812                needSep = true;
13813            }
13814            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13815            pw.print(": "); pw.println(uidRec);
13816        }
13817        return printed;
13818    }
13819
13820    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13821            int opti, boolean dumpAll, String dumpPackage) {
13822        boolean needSep = false;
13823        boolean printedAnything = false;
13824        int numPers = 0;
13825
13826        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13827
13828        if (dumpAll) {
13829            final int NP = mProcessNames.getMap().size();
13830            for (int ip=0; ip<NP; ip++) {
13831                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13832                final int NA = procs.size();
13833                for (int ia=0; ia<NA; ia++) {
13834                    ProcessRecord r = procs.valueAt(ia);
13835                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13836                        continue;
13837                    }
13838                    if (!needSep) {
13839                        pw.println("  All known processes:");
13840                        needSep = true;
13841                        printedAnything = true;
13842                    }
13843                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13844                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13845                        pw.print(" "); pw.println(r);
13846                    r.dump(pw, "    ");
13847                    if (r.persistent) {
13848                        numPers++;
13849                    }
13850                }
13851            }
13852        }
13853
13854        if (mIsolatedProcesses.size() > 0) {
13855            boolean printed = false;
13856            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13857                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13858                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13859                    continue;
13860                }
13861                if (!printed) {
13862                    if (needSep) {
13863                        pw.println();
13864                    }
13865                    pw.println("  Isolated process list (sorted by uid):");
13866                    printedAnything = true;
13867                    printed = true;
13868                    needSep = true;
13869                }
13870                pw.println(String.format("%sIsolated #%2d: %s",
13871                        "    ", i, r.toString()));
13872            }
13873        }
13874
13875        if (mActiveUids.size() > 0) {
13876            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13877                printedAnything = needSep = true;
13878            }
13879        }
13880        if (mValidateUids.size() > 0) {
13881            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13882                printedAnything = needSep = true;
13883            }
13884        }
13885
13886        if (mLruProcesses.size() > 0) {
13887            if (needSep) {
13888                pw.println();
13889            }
13890            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13891                    pw.print(" total, non-act at ");
13892                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13893                    pw.print(", non-svc at ");
13894                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13895                    pw.println("):");
13896            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13897            needSep = true;
13898            printedAnything = true;
13899        }
13900
13901        if (dumpAll || dumpPackage != null) {
13902            synchronized (mPidsSelfLocked) {
13903                boolean printed = false;
13904                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13905                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13906                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13907                        continue;
13908                    }
13909                    if (!printed) {
13910                        if (needSep) pw.println();
13911                        needSep = true;
13912                        pw.println("  PID mappings:");
13913                        printed = true;
13914                        printedAnything = true;
13915                    }
13916                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13917                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13918                }
13919            }
13920        }
13921
13922        if (mForegroundProcesses.size() > 0) {
13923            synchronized (mPidsSelfLocked) {
13924                boolean printed = false;
13925                for (int i=0; i<mForegroundProcesses.size(); i++) {
13926                    ProcessRecord r = mPidsSelfLocked.get(
13927                            mForegroundProcesses.valueAt(i).pid);
13928                    if (dumpPackage != null && (r == null
13929                            || !r.pkgList.containsKey(dumpPackage))) {
13930                        continue;
13931                    }
13932                    if (!printed) {
13933                        if (needSep) pw.println();
13934                        needSep = true;
13935                        pw.println("  Foreground Processes:");
13936                        printed = true;
13937                        printedAnything = true;
13938                    }
13939                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13940                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13941                }
13942            }
13943        }
13944
13945        if (mPersistentStartingProcesses.size() > 0) {
13946            if (needSep) pw.println();
13947            needSep = true;
13948            printedAnything = true;
13949            pw.println("  Persisent processes that are starting:");
13950            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13951                    "Starting Norm", "Restarting PERS", dumpPackage);
13952        }
13953
13954        if (mRemovedProcesses.size() > 0) {
13955            if (needSep) pw.println();
13956            needSep = true;
13957            printedAnything = true;
13958            pw.println("  Processes that are being removed:");
13959            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13960                    "Removed Norm", "Removed PERS", dumpPackage);
13961        }
13962
13963        if (mProcessesOnHold.size() > 0) {
13964            if (needSep) pw.println();
13965            needSep = true;
13966            printedAnything = true;
13967            pw.println("  Processes that are on old until the system is ready:");
13968            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13969                    "OnHold Norm", "OnHold PERS", dumpPackage);
13970        }
13971
13972        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13973
13974        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
13975        if (needSep) {
13976            printedAnything = true;
13977        }
13978
13979        if (dumpPackage == null) {
13980            pw.println();
13981            needSep = false;
13982            mUserController.dump(pw, dumpAll);
13983        }
13984        if (mHomeProcess != null && (dumpPackage == null
13985                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13986            if (needSep) {
13987                pw.println();
13988                needSep = false;
13989            }
13990            pw.println("  mHomeProcess: " + mHomeProcess);
13991        }
13992        if (mPreviousProcess != null && (dumpPackage == null
13993                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13994            if (needSep) {
13995                pw.println();
13996                needSep = false;
13997            }
13998            pw.println("  mPreviousProcess: " + mPreviousProcess);
13999        }
14000        if (dumpAll) {
14001            StringBuilder sb = new StringBuilder(128);
14002            sb.append("  mPreviousProcessVisibleTime: ");
14003            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14004            pw.println(sb);
14005        }
14006        if (mHeavyWeightProcess != null && (dumpPackage == null
14007                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14008            if (needSep) {
14009                pw.println();
14010                needSep = false;
14011            }
14012            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14013        }
14014        if (dumpPackage == null) {
14015            pw.println("  mConfiguration: " + mConfiguration);
14016        }
14017        if (dumpAll) {
14018            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14019            if (mCompatModePackages.getPackages().size() > 0) {
14020                boolean printed = false;
14021                for (Map.Entry<String, Integer> entry
14022                        : mCompatModePackages.getPackages().entrySet()) {
14023                    String pkg = entry.getKey();
14024                    int mode = entry.getValue();
14025                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14026                        continue;
14027                    }
14028                    if (!printed) {
14029                        pw.println("  mScreenCompatPackages:");
14030                        printed = true;
14031                    }
14032                    pw.print("    "); pw.print(pkg); pw.print(": ");
14033                            pw.print(mode); pw.println();
14034                }
14035            }
14036        }
14037        if (dumpPackage == null) {
14038            pw.println("  mWakefulness="
14039                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14040            pw.println("  mSleepTokens=" + mSleepTokens);
14041            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14042                    + lockScreenShownToString());
14043            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14044            if (mRunningVoice != null) {
14045                pw.println("  mRunningVoice=" + mRunningVoice);
14046                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14047            }
14048        }
14049        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14050                || mOrigWaitForDebugger) {
14051            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14052                    || dumpPackage.equals(mOrigDebugApp)) {
14053                if (needSep) {
14054                    pw.println();
14055                    needSep = false;
14056                }
14057                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14058                        + " mDebugTransient=" + mDebugTransient
14059                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14060            }
14061        }
14062        if (mCurAppTimeTracker != null) {
14063            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14064        }
14065        if (mMemWatchProcesses.getMap().size() > 0) {
14066            pw.println("  Mem watch processes:");
14067            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14068                    = mMemWatchProcesses.getMap();
14069            for (int i=0; i<procs.size(); i++) {
14070                final String proc = procs.keyAt(i);
14071                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14072                for (int j=0; j<uids.size(); j++) {
14073                    if (needSep) {
14074                        pw.println();
14075                        needSep = false;
14076                    }
14077                    StringBuilder sb = new StringBuilder();
14078                    sb.append("    ").append(proc).append('/');
14079                    UserHandle.formatUid(sb, uids.keyAt(j));
14080                    Pair<Long, String> val = uids.valueAt(j);
14081                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14082                    if (val.second != null) {
14083                        sb.append(", report to ").append(val.second);
14084                    }
14085                    pw.println(sb.toString());
14086                }
14087            }
14088            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14089            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14090            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14091                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14092        }
14093        if (mTrackAllocationApp != null) {
14094            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14095                if (needSep) {
14096                    pw.println();
14097                    needSep = false;
14098                }
14099                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14100            }
14101        }
14102        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14103                || mProfileFd != null) {
14104            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14105                if (needSep) {
14106                    pw.println();
14107                    needSep = false;
14108                }
14109                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14110                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14111                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14112                        + mAutoStopProfiler);
14113                pw.println("  mProfileType=" + mProfileType);
14114            }
14115        }
14116        if (mNativeDebuggingApp != null) {
14117            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14118                if (needSep) {
14119                    pw.println();
14120                    needSep = false;
14121                }
14122                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14123            }
14124        }
14125        if (dumpPackage == null) {
14126            if (mAlwaysFinishActivities || mLenientBackgroundCheck || mController != null) {
14127                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14128                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck
14129                        + " mController=" + mController);
14130            }
14131            if (dumpAll) {
14132                pw.println("  Total persistent processes: " + numPers);
14133                pw.println("  mProcessesReady=" + mProcessesReady
14134                        + " mSystemReady=" + mSystemReady
14135                        + " mBooted=" + mBooted
14136                        + " mFactoryTest=" + mFactoryTest);
14137                pw.println("  mBooting=" + mBooting
14138                        + " mCallFinishBooting=" + mCallFinishBooting
14139                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14140                pw.print("  mLastPowerCheckRealtime=");
14141                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14142                        pw.println("");
14143                pw.print("  mLastPowerCheckUptime=");
14144                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14145                        pw.println("");
14146                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14147                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14148                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14149                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14150                        + " (" + mLruProcesses.size() + " total)"
14151                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14152                        + " mNumServiceProcs=" + mNumServiceProcs
14153                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14154                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14155                        + " mLastMemoryLevel" + mLastMemoryLevel
14156                        + " mLastNumProcesses" + mLastNumProcesses);
14157                long now = SystemClock.uptimeMillis();
14158                pw.print("  mLastIdleTime=");
14159                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14160                        pw.print(" mLowRamSinceLastIdle=");
14161                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14162                        pw.println();
14163            }
14164        }
14165
14166        if (!printedAnything) {
14167            pw.println("  (nothing)");
14168        }
14169    }
14170
14171    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14172            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14173        if (mProcessesToGc.size() > 0) {
14174            boolean printed = false;
14175            long now = SystemClock.uptimeMillis();
14176            for (int i=0; i<mProcessesToGc.size(); i++) {
14177                ProcessRecord proc = mProcessesToGc.get(i);
14178                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14179                    continue;
14180                }
14181                if (!printed) {
14182                    if (needSep) pw.println();
14183                    needSep = true;
14184                    pw.println("  Processes that are waiting to GC:");
14185                    printed = true;
14186                }
14187                pw.print("    Process "); pw.println(proc);
14188                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14189                        pw.print(", last gced=");
14190                        pw.print(now-proc.lastRequestedGc);
14191                        pw.print(" ms ago, last lowMem=");
14192                        pw.print(now-proc.lastLowMemory);
14193                        pw.println(" ms ago");
14194
14195            }
14196        }
14197        return needSep;
14198    }
14199
14200    void printOomLevel(PrintWriter pw, String name, int adj) {
14201        pw.print("    ");
14202        if (adj >= 0) {
14203            pw.print(' ');
14204            if (adj < 10) pw.print(' ');
14205        } else {
14206            if (adj > -10) pw.print(' ');
14207        }
14208        pw.print(adj);
14209        pw.print(": ");
14210        pw.print(name);
14211        pw.print(" (");
14212        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14213        pw.println(")");
14214    }
14215
14216    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14217            int opti, boolean dumpAll) {
14218        boolean needSep = false;
14219
14220        if (mLruProcesses.size() > 0) {
14221            if (needSep) pw.println();
14222            needSep = true;
14223            pw.println("  OOM levels:");
14224            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14225            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14226            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14227            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14228            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14229            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14230            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14231            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14232            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14233            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14234            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14235            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14236            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14237            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14238
14239            if (needSep) pw.println();
14240            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14241                    pw.print(" total, non-act at ");
14242                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14243                    pw.print(", non-svc at ");
14244                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14245                    pw.println("):");
14246            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14247            needSep = true;
14248        }
14249
14250        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14251
14252        pw.println();
14253        pw.println("  mHomeProcess: " + mHomeProcess);
14254        pw.println("  mPreviousProcess: " + mPreviousProcess);
14255        if (mHeavyWeightProcess != null) {
14256            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14257        }
14258
14259        return true;
14260    }
14261
14262    /**
14263     * There are three ways to call this:
14264     *  - no provider specified: dump all the providers
14265     *  - a flattened component name that matched an existing provider was specified as the
14266     *    first arg: dump that one provider
14267     *  - the first arg isn't the flattened component name of an existing provider:
14268     *    dump all providers whose component contains the first arg as a substring
14269     */
14270    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14271            int opti, boolean dumpAll) {
14272        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14273    }
14274
14275    static class ItemMatcher {
14276        ArrayList<ComponentName> components;
14277        ArrayList<String> strings;
14278        ArrayList<Integer> objects;
14279        boolean all;
14280
14281        ItemMatcher() {
14282            all = true;
14283        }
14284
14285        void build(String name) {
14286            ComponentName componentName = ComponentName.unflattenFromString(name);
14287            if (componentName != null) {
14288                if (components == null) {
14289                    components = new ArrayList<ComponentName>();
14290                }
14291                components.add(componentName);
14292                all = false;
14293            } else {
14294                int objectId = 0;
14295                // Not a '/' separated full component name; maybe an object ID?
14296                try {
14297                    objectId = Integer.parseInt(name, 16);
14298                    if (objects == null) {
14299                        objects = new ArrayList<Integer>();
14300                    }
14301                    objects.add(objectId);
14302                    all = false;
14303                } catch (RuntimeException e) {
14304                    // Not an integer; just do string match.
14305                    if (strings == null) {
14306                        strings = new ArrayList<String>();
14307                    }
14308                    strings.add(name);
14309                    all = false;
14310                }
14311            }
14312        }
14313
14314        int build(String[] args, int opti) {
14315            for (; opti<args.length; opti++) {
14316                String name = args[opti];
14317                if ("--".equals(name)) {
14318                    return opti+1;
14319                }
14320                build(name);
14321            }
14322            return opti;
14323        }
14324
14325        boolean match(Object object, ComponentName comp) {
14326            if (all) {
14327                return true;
14328            }
14329            if (components != null) {
14330                for (int i=0; i<components.size(); i++) {
14331                    if (components.get(i).equals(comp)) {
14332                        return true;
14333                    }
14334                }
14335            }
14336            if (objects != null) {
14337                for (int i=0; i<objects.size(); i++) {
14338                    if (System.identityHashCode(object) == objects.get(i)) {
14339                        return true;
14340                    }
14341                }
14342            }
14343            if (strings != null) {
14344                String flat = comp.flattenToString();
14345                for (int i=0; i<strings.size(); i++) {
14346                    if (flat.contains(strings.get(i))) {
14347                        return true;
14348                    }
14349                }
14350            }
14351            return false;
14352        }
14353    }
14354
14355    /**
14356     * There are three things that cmd can be:
14357     *  - a flattened component name that matches an existing activity
14358     *  - the cmd arg isn't the flattened component name of an existing activity:
14359     *    dump all activity whose component contains the cmd as a substring
14360     *  - A hex number of the ActivityRecord object instance.
14361     */
14362    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14363            int opti, boolean dumpAll) {
14364        ArrayList<ActivityRecord> activities;
14365
14366        synchronized (this) {
14367            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14368        }
14369
14370        if (activities.size() <= 0) {
14371            return false;
14372        }
14373
14374        String[] newArgs = new String[args.length - opti];
14375        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14376
14377        TaskRecord lastTask = null;
14378        boolean needSep = false;
14379        for (int i=activities.size()-1; i>=0; i--) {
14380            ActivityRecord r = activities.get(i);
14381            if (needSep) {
14382                pw.println();
14383            }
14384            needSep = true;
14385            synchronized (this) {
14386                if (lastTask != r.task) {
14387                    lastTask = r.task;
14388                    pw.print("TASK "); pw.print(lastTask.affinity);
14389                            pw.print(" id="); pw.println(lastTask.taskId);
14390                    if (dumpAll) {
14391                        lastTask.dump(pw, "  ");
14392                    }
14393                }
14394            }
14395            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14396        }
14397        return true;
14398    }
14399
14400    /**
14401     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14402     * there is a thread associated with the activity.
14403     */
14404    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14405            final ActivityRecord r, String[] args, boolean dumpAll) {
14406        String innerPrefix = prefix + "  ";
14407        synchronized (this) {
14408            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14409                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14410                    pw.print(" pid=");
14411                    if (r.app != null) pw.println(r.app.pid);
14412                    else pw.println("(not running)");
14413            if (dumpAll) {
14414                r.dump(pw, innerPrefix);
14415            }
14416        }
14417        if (r.app != null && r.app.thread != null) {
14418            // flush anything that is already in the PrintWriter since the thread is going
14419            // to write to the file descriptor directly
14420            pw.flush();
14421            try {
14422                TransferPipe tp = new TransferPipe();
14423                try {
14424                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14425                            r.appToken, innerPrefix, args);
14426                    tp.go(fd);
14427                } finally {
14428                    tp.kill();
14429                }
14430            } catch (IOException e) {
14431                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14432            } catch (RemoteException e) {
14433                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14434            }
14435        }
14436    }
14437
14438    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14439            int opti, boolean dumpAll, String dumpPackage) {
14440        boolean needSep = false;
14441        boolean onlyHistory = false;
14442        boolean printedAnything = false;
14443
14444        if ("history".equals(dumpPackage)) {
14445            if (opti < args.length && "-s".equals(args[opti])) {
14446                dumpAll = false;
14447            }
14448            onlyHistory = true;
14449            dumpPackage = null;
14450        }
14451
14452        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14453        if (!onlyHistory && dumpAll) {
14454            if (mRegisteredReceivers.size() > 0) {
14455                boolean printed = false;
14456                Iterator it = mRegisteredReceivers.values().iterator();
14457                while (it.hasNext()) {
14458                    ReceiverList r = (ReceiverList)it.next();
14459                    if (dumpPackage != null && (r.app == null ||
14460                            !dumpPackage.equals(r.app.info.packageName))) {
14461                        continue;
14462                    }
14463                    if (!printed) {
14464                        pw.println("  Registered Receivers:");
14465                        needSep = true;
14466                        printed = true;
14467                        printedAnything = true;
14468                    }
14469                    pw.print("  * "); pw.println(r);
14470                    r.dump(pw, "    ");
14471                }
14472            }
14473
14474            if (mReceiverResolver.dump(pw, needSep ?
14475                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14476                    "    ", dumpPackage, false, false)) {
14477                needSep = true;
14478                printedAnything = true;
14479            }
14480        }
14481
14482        for (BroadcastQueue q : mBroadcastQueues) {
14483            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14484            printedAnything |= needSep;
14485        }
14486
14487        needSep = true;
14488
14489        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14490            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14491                if (needSep) {
14492                    pw.println();
14493                }
14494                needSep = true;
14495                printedAnything = true;
14496                pw.print("  Sticky broadcasts for user ");
14497                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14498                StringBuilder sb = new StringBuilder(128);
14499                for (Map.Entry<String, ArrayList<Intent>> ent
14500                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14501                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14502                    if (dumpAll) {
14503                        pw.println(":");
14504                        ArrayList<Intent> intents = ent.getValue();
14505                        final int N = intents.size();
14506                        for (int i=0; i<N; i++) {
14507                            sb.setLength(0);
14508                            sb.append("    Intent: ");
14509                            intents.get(i).toShortString(sb, false, true, false, false);
14510                            pw.println(sb.toString());
14511                            Bundle bundle = intents.get(i).getExtras();
14512                            if (bundle != null) {
14513                                pw.print("      ");
14514                                pw.println(bundle.toString());
14515                            }
14516                        }
14517                    } else {
14518                        pw.println("");
14519                    }
14520                }
14521            }
14522        }
14523
14524        if (!onlyHistory && dumpAll) {
14525            pw.println();
14526            for (BroadcastQueue queue : mBroadcastQueues) {
14527                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14528                        + queue.mBroadcastsScheduled);
14529            }
14530            pw.println("  mHandler:");
14531            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14532            needSep = true;
14533            printedAnything = true;
14534        }
14535
14536        if (!printedAnything) {
14537            pw.println("  (nothing)");
14538        }
14539    }
14540
14541    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14542            int opti, boolean dumpAll, String dumpPackage) {
14543        boolean needSep;
14544        boolean printedAnything = false;
14545
14546        ItemMatcher matcher = new ItemMatcher();
14547        matcher.build(args, opti);
14548
14549        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14550
14551        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14552        printedAnything |= needSep;
14553
14554        if (mLaunchingProviders.size() > 0) {
14555            boolean printed = false;
14556            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14557                ContentProviderRecord r = mLaunchingProviders.get(i);
14558                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14559                    continue;
14560                }
14561                if (!printed) {
14562                    if (needSep) pw.println();
14563                    needSep = true;
14564                    pw.println("  Launching content providers:");
14565                    printed = true;
14566                    printedAnything = true;
14567                }
14568                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14569                        pw.println(r);
14570            }
14571        }
14572
14573        if (!printedAnything) {
14574            pw.println("  (nothing)");
14575        }
14576    }
14577
14578    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14579            int opti, boolean dumpAll, String dumpPackage) {
14580        boolean needSep = false;
14581        boolean printedAnything = false;
14582
14583        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14584
14585        if (mGrantedUriPermissions.size() > 0) {
14586            boolean printed = false;
14587            int dumpUid = -2;
14588            if (dumpPackage != null) {
14589                try {
14590                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14591                            MATCH_UNINSTALLED_PACKAGES, 0);
14592                } catch (NameNotFoundException e) {
14593                    dumpUid = -1;
14594                }
14595            }
14596            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14597                int uid = mGrantedUriPermissions.keyAt(i);
14598                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14599                    continue;
14600                }
14601                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14602                if (!printed) {
14603                    if (needSep) pw.println();
14604                    needSep = true;
14605                    pw.println("  Granted Uri Permissions:");
14606                    printed = true;
14607                    printedAnything = true;
14608                }
14609                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14610                for (UriPermission perm : perms.values()) {
14611                    pw.print("    "); pw.println(perm);
14612                    if (dumpAll) {
14613                        perm.dump(pw, "      ");
14614                    }
14615                }
14616            }
14617        }
14618
14619        if (!printedAnything) {
14620            pw.println("  (nothing)");
14621        }
14622    }
14623
14624    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14625            int opti, boolean dumpAll, String dumpPackage) {
14626        boolean printed = false;
14627
14628        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14629
14630        if (mIntentSenderRecords.size() > 0) {
14631            Iterator<WeakReference<PendingIntentRecord>> it
14632                    = mIntentSenderRecords.values().iterator();
14633            while (it.hasNext()) {
14634                WeakReference<PendingIntentRecord> ref = it.next();
14635                PendingIntentRecord rec = ref != null ? ref.get(): null;
14636                if (dumpPackage != null && (rec == null
14637                        || !dumpPackage.equals(rec.key.packageName))) {
14638                    continue;
14639                }
14640                printed = true;
14641                if (rec != null) {
14642                    pw.print("  * "); pw.println(rec);
14643                    if (dumpAll) {
14644                        rec.dump(pw, "    ");
14645                    }
14646                } else {
14647                    pw.print("  * "); pw.println(ref);
14648                }
14649            }
14650        }
14651
14652        if (!printed) {
14653            pw.println("  (nothing)");
14654        }
14655    }
14656
14657    private static final int dumpProcessList(PrintWriter pw,
14658            ActivityManagerService service, List list,
14659            String prefix, String normalLabel, String persistentLabel,
14660            String dumpPackage) {
14661        int numPers = 0;
14662        final int N = list.size()-1;
14663        for (int i=N; i>=0; i--) {
14664            ProcessRecord r = (ProcessRecord)list.get(i);
14665            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14666                continue;
14667            }
14668            pw.println(String.format("%s%s #%2d: %s",
14669                    prefix, (r.persistent ? persistentLabel : normalLabel),
14670                    i, r.toString()));
14671            if (r.persistent) {
14672                numPers++;
14673            }
14674        }
14675        return numPers;
14676    }
14677
14678    private static final boolean dumpProcessOomList(PrintWriter pw,
14679            ActivityManagerService service, List<ProcessRecord> origList,
14680            String prefix, String normalLabel, String persistentLabel,
14681            boolean inclDetails, String dumpPackage) {
14682
14683        ArrayList<Pair<ProcessRecord, Integer>> list
14684                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14685        for (int i=0; i<origList.size(); i++) {
14686            ProcessRecord r = origList.get(i);
14687            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14688                continue;
14689            }
14690            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14691        }
14692
14693        if (list.size() <= 0) {
14694            return false;
14695        }
14696
14697        Comparator<Pair<ProcessRecord, Integer>> comparator
14698                = new Comparator<Pair<ProcessRecord, Integer>>() {
14699            @Override
14700            public int compare(Pair<ProcessRecord, Integer> object1,
14701                    Pair<ProcessRecord, Integer> object2) {
14702                if (object1.first.setAdj != object2.first.setAdj) {
14703                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14704                }
14705                if (object1.first.setProcState != object2.first.setProcState) {
14706                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14707                }
14708                if (object1.second.intValue() != object2.second.intValue()) {
14709                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14710                }
14711                return 0;
14712            }
14713        };
14714
14715        Collections.sort(list, comparator);
14716
14717        final long curRealtime = SystemClock.elapsedRealtime();
14718        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14719        final long curUptime = SystemClock.uptimeMillis();
14720        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14721
14722        for (int i=list.size()-1; i>=0; i--) {
14723            ProcessRecord r = list.get(i).first;
14724            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14725            char schedGroup;
14726            switch (r.setSchedGroup) {
14727                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14728                    schedGroup = 'B';
14729                    break;
14730                case Process.THREAD_GROUP_DEFAULT:
14731                    schedGroup = 'F';
14732                    break;
14733                case Process.THREAD_GROUP_TOP_APP:
14734                    schedGroup = 'T';
14735                    break;
14736                default:
14737                    schedGroup = '?';
14738                    break;
14739            }
14740            char foreground;
14741            if (r.foregroundActivities) {
14742                foreground = 'A';
14743            } else if (r.foregroundServices) {
14744                foreground = 'S';
14745            } else {
14746                foreground = ' ';
14747            }
14748            String procState = ProcessList.makeProcStateString(r.curProcState);
14749            pw.print(prefix);
14750            pw.print(r.persistent ? persistentLabel : normalLabel);
14751            pw.print(" #");
14752            int num = (origList.size()-1)-list.get(i).second;
14753            if (num < 10) pw.print(' ');
14754            pw.print(num);
14755            pw.print(": ");
14756            pw.print(oomAdj);
14757            pw.print(' ');
14758            pw.print(schedGroup);
14759            pw.print('/');
14760            pw.print(foreground);
14761            pw.print('/');
14762            pw.print(procState);
14763            pw.print(" trm:");
14764            if (r.trimMemoryLevel < 10) pw.print(' ');
14765            pw.print(r.trimMemoryLevel);
14766            pw.print(' ');
14767            pw.print(r.toShortString());
14768            pw.print(" (");
14769            pw.print(r.adjType);
14770            pw.println(')');
14771            if (r.adjSource != null || r.adjTarget != null) {
14772                pw.print(prefix);
14773                pw.print("    ");
14774                if (r.adjTarget instanceof ComponentName) {
14775                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14776                } else if (r.adjTarget != null) {
14777                    pw.print(r.adjTarget.toString());
14778                } else {
14779                    pw.print("{null}");
14780                }
14781                pw.print("<=");
14782                if (r.adjSource instanceof ProcessRecord) {
14783                    pw.print("Proc{");
14784                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14785                    pw.println("}");
14786                } else if (r.adjSource != null) {
14787                    pw.println(r.adjSource.toString());
14788                } else {
14789                    pw.println("{null}");
14790                }
14791            }
14792            if (inclDetails) {
14793                pw.print(prefix);
14794                pw.print("    ");
14795                pw.print("oom: max="); pw.print(r.maxAdj);
14796                pw.print(" curRaw="); pw.print(r.curRawAdj);
14797                pw.print(" setRaw="); pw.print(r.setRawAdj);
14798                pw.print(" cur="); pw.print(r.curAdj);
14799                pw.print(" set="); pw.println(r.setAdj);
14800                pw.print(prefix);
14801                pw.print("    ");
14802                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14803                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14804                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14805                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14806                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14807                pw.println();
14808                pw.print(prefix);
14809                pw.print("    ");
14810                pw.print("cached="); pw.print(r.cached);
14811                pw.print(" empty="); pw.print(r.empty);
14812                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14813
14814                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14815                    if (r.lastWakeTime != 0) {
14816                        long wtime;
14817                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14818                        synchronized (stats) {
14819                            wtime = stats.getProcessWakeTime(r.info.uid,
14820                                    r.pid, curRealtime);
14821                        }
14822                        long timeUsed = wtime - r.lastWakeTime;
14823                        pw.print(prefix);
14824                        pw.print("    ");
14825                        pw.print("keep awake over ");
14826                        TimeUtils.formatDuration(realtimeSince, pw);
14827                        pw.print(" used ");
14828                        TimeUtils.formatDuration(timeUsed, pw);
14829                        pw.print(" (");
14830                        pw.print((timeUsed*100)/realtimeSince);
14831                        pw.println("%)");
14832                    }
14833                    if (r.lastCpuTime != 0) {
14834                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14835                        pw.print(prefix);
14836                        pw.print("    ");
14837                        pw.print("run cpu over ");
14838                        TimeUtils.formatDuration(uptimeSince, pw);
14839                        pw.print(" used ");
14840                        TimeUtils.formatDuration(timeUsed, pw);
14841                        pw.print(" (");
14842                        pw.print((timeUsed*100)/uptimeSince);
14843                        pw.println("%)");
14844                    }
14845                }
14846            }
14847        }
14848        return true;
14849    }
14850
14851    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14852            String[] args) {
14853        ArrayList<ProcessRecord> procs;
14854        synchronized (this) {
14855            if (args != null && args.length > start
14856                    && args[start].charAt(0) != '-') {
14857                procs = new ArrayList<ProcessRecord>();
14858                int pid = -1;
14859                try {
14860                    pid = Integer.parseInt(args[start]);
14861                } catch (NumberFormatException e) {
14862                }
14863                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14864                    ProcessRecord proc = mLruProcesses.get(i);
14865                    if (proc.pid == pid) {
14866                        procs.add(proc);
14867                    } else if (allPkgs && proc.pkgList != null
14868                            && proc.pkgList.containsKey(args[start])) {
14869                        procs.add(proc);
14870                    } else if (proc.processName.equals(args[start])) {
14871                        procs.add(proc);
14872                    }
14873                }
14874                if (procs.size() <= 0) {
14875                    return null;
14876                }
14877            } else {
14878                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14879            }
14880        }
14881        return procs;
14882    }
14883
14884    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14885            PrintWriter pw, String[] args) {
14886        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14887        if (procs == null) {
14888            pw.println("No process found for: " + args[0]);
14889            return;
14890        }
14891
14892        long uptime = SystemClock.uptimeMillis();
14893        long realtime = SystemClock.elapsedRealtime();
14894        pw.println("Applications Graphics Acceleration Info:");
14895        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14896
14897        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14898            ProcessRecord r = procs.get(i);
14899            if (r.thread != null) {
14900                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14901                pw.flush();
14902                try {
14903                    TransferPipe tp = new TransferPipe();
14904                    try {
14905                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14906                        tp.go(fd);
14907                    } finally {
14908                        tp.kill();
14909                    }
14910                } catch (IOException e) {
14911                    pw.println("Failure while dumping the app: " + r);
14912                    pw.flush();
14913                } catch (RemoteException e) {
14914                    pw.println("Got a RemoteException while dumping the app " + r);
14915                    pw.flush();
14916                }
14917            }
14918        }
14919    }
14920
14921    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14922        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14923        if (procs == null) {
14924            pw.println("No process found for: " + args[0]);
14925            return;
14926        }
14927
14928        pw.println("Applications Database Info:");
14929
14930        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14931            ProcessRecord r = procs.get(i);
14932            if (r.thread != null) {
14933                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14934                pw.flush();
14935                try {
14936                    TransferPipe tp = new TransferPipe();
14937                    try {
14938                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14939                        tp.go(fd);
14940                    } finally {
14941                        tp.kill();
14942                    }
14943                } catch (IOException e) {
14944                    pw.println("Failure while dumping the app: " + r);
14945                    pw.flush();
14946                } catch (RemoteException e) {
14947                    pw.println("Got a RemoteException while dumping the app " + r);
14948                    pw.flush();
14949                }
14950            }
14951        }
14952    }
14953
14954    final static class MemItem {
14955        final boolean isProc;
14956        final String label;
14957        final String shortLabel;
14958        final long pss;
14959        final long swapPss;
14960        final int id;
14961        final boolean hasActivities;
14962        ArrayList<MemItem> subitems;
14963
14964        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
14965                boolean _hasActivities) {
14966            isProc = true;
14967            label = _label;
14968            shortLabel = _shortLabel;
14969            pss = _pss;
14970            swapPss = _swapPss;
14971            id = _id;
14972            hasActivities = _hasActivities;
14973        }
14974
14975        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
14976            isProc = false;
14977            label = _label;
14978            shortLabel = _shortLabel;
14979            pss = _pss;
14980            swapPss = _swapPss;
14981            id = _id;
14982            hasActivities = false;
14983        }
14984    }
14985
14986    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14987            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
14988        if (sort && !isCompact) {
14989            Collections.sort(items, new Comparator<MemItem>() {
14990                @Override
14991                public int compare(MemItem lhs, MemItem rhs) {
14992                    if (lhs.pss < rhs.pss) {
14993                        return 1;
14994                    } else if (lhs.pss > rhs.pss) {
14995                        return -1;
14996                    }
14997                    return 0;
14998                }
14999            });
15000        }
15001
15002        for (int i=0; i<items.size(); i++) {
15003            MemItem mi = items.get(i);
15004            if (!isCompact) {
15005                if (dumpSwapPss) {
15006                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15007                            mi.label, stringifyKBSize(mi.swapPss));
15008                } else {
15009                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15010                }
15011            } else if (mi.isProc) {
15012                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15013                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15014                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15015                pw.println(mi.hasActivities ? ",a" : ",e");
15016            } else {
15017                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15018                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15019            }
15020            if (mi.subitems != null) {
15021                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15022                        true, isCompact, dumpSwapPss);
15023            }
15024        }
15025    }
15026
15027    // These are in KB.
15028    static final long[] DUMP_MEM_BUCKETS = new long[] {
15029        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15030        120*1024, 160*1024, 200*1024,
15031        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15032        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15033    };
15034
15035    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15036            boolean stackLike) {
15037        int start = label.lastIndexOf('.');
15038        if (start >= 0) start++;
15039        else start = 0;
15040        int end = label.length();
15041        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15042            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15043                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15044                out.append(bucket);
15045                out.append(stackLike ? "MB." : "MB ");
15046                out.append(label, start, end);
15047                return;
15048            }
15049        }
15050        out.append(memKB/1024);
15051        out.append(stackLike ? "MB." : "MB ");
15052        out.append(label, start, end);
15053    }
15054
15055    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15056            ProcessList.NATIVE_ADJ,
15057            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15058            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15059            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15060            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15061            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15062            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15063    };
15064    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15065            "Native",
15066            "System", "Persistent", "Persistent Service", "Foreground",
15067            "Visible", "Perceptible",
15068            "Heavy Weight", "Backup",
15069            "A Services", "Home",
15070            "Previous", "B Services", "Cached"
15071    };
15072    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15073            "native",
15074            "sys", "pers", "persvc", "fore",
15075            "vis", "percept",
15076            "heavy", "backup",
15077            "servicea", "home",
15078            "prev", "serviceb", "cached"
15079    };
15080
15081    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15082            long realtime, boolean isCheckinRequest, boolean isCompact) {
15083        if (isCompact) {
15084            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15085        }
15086        if (isCheckinRequest || isCompact) {
15087            // short checkin version
15088            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15089        } else {
15090            pw.println("Applications Memory Usage (in Kilobytes):");
15091            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15092        }
15093    }
15094
15095    private static final int KSM_SHARED = 0;
15096    private static final int KSM_SHARING = 1;
15097    private static final int KSM_UNSHARED = 2;
15098    private static final int KSM_VOLATILE = 3;
15099
15100    private final long[] getKsmInfo() {
15101        long[] longOut = new long[4];
15102        final int[] SINGLE_LONG_FORMAT = new int[] {
15103            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15104        };
15105        long[] longTmp = new long[1];
15106        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15107                SINGLE_LONG_FORMAT, null, longTmp, null);
15108        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15109        longTmp[0] = 0;
15110        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15111                SINGLE_LONG_FORMAT, null, longTmp, null);
15112        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15113        longTmp[0] = 0;
15114        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15115                SINGLE_LONG_FORMAT, null, longTmp, null);
15116        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15117        longTmp[0] = 0;
15118        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15119                SINGLE_LONG_FORMAT, null, longTmp, null);
15120        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15121        return longOut;
15122    }
15123
15124    private static String stringifySize(long size, int order) {
15125        Locale locale = Locale.US;
15126        switch (order) {
15127            case 1:
15128                return String.format(locale, "%,13d", size);
15129            case 1024:
15130                return String.format(locale, "%,9dK", size / 1024);
15131            case 1024 * 1024:
15132                return String.format(locale, "%,5dM", size / 1024 / 1024);
15133            case 1024 * 1024 * 1024:
15134                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15135            default:
15136                throw new IllegalArgumentException("Invalid size order");
15137        }
15138    }
15139
15140    private static String stringifyKBSize(long size) {
15141        return stringifySize(size * 1024, 1024);
15142    }
15143
15144    // Update this version number in case you change the 'compact' format
15145    private static final int MEMINFO_COMPACT_VERSION = 1;
15146
15147    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15148            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15149        boolean dumpDetails = false;
15150        boolean dumpFullDetails = false;
15151        boolean dumpDalvik = false;
15152        boolean dumpSummaryOnly = false;
15153        boolean dumpUnreachable = 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 ("--unreachable".equals(opt)) {
15183                dumpUnreachable = true;
15184            } else if ("--oom".equals(opt)) {
15185                oomOnly = true;
15186            } else if ("--local".equals(opt)) {
15187                localOnly = true;
15188            } else if ("--package".equals(opt)) {
15189                packages = true;
15190            } else if ("--checkin".equals(opt)) {
15191                isCheckinRequest = true;
15192
15193            } else if ("-h".equals(opt)) {
15194                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15195                pw.println("  -a: include all available information for each process.");
15196                pw.println("  -d: include dalvik details.");
15197                pw.println("  -c: dump in a compact machine-parseable representation.");
15198                pw.println("  -s: dump only summary of application memory usage.");
15199                pw.println("  -S: dump also SwapPss.");
15200                pw.println("  --oom: only show processes organized by oom adj.");
15201                pw.println("  --local: only collect details locally, don't call process.");
15202                pw.println("  --package: interpret process arg as package, dumping all");
15203                pw.println("             processes that have loaded that package.");
15204                pw.println("  --checkin: dump data for a checkin");
15205                pw.println("If [process] is specified it can be the name or ");
15206                pw.println("pid of a specific process to dump.");
15207                return;
15208            } else {
15209                pw.println("Unknown argument: " + opt + "; use -h for help");
15210            }
15211        }
15212
15213        long uptime = SystemClock.uptimeMillis();
15214        long realtime = SystemClock.elapsedRealtime();
15215        final long[] tmpLong = new long[1];
15216
15217        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15218        if (procs == null) {
15219            // No Java processes.  Maybe they want to print a native process.
15220            if (args != null && args.length > opti
15221                    && args[opti].charAt(0) != '-') {
15222                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15223                        = new ArrayList<ProcessCpuTracker.Stats>();
15224                updateCpuStatsNow();
15225                int findPid = -1;
15226                try {
15227                    findPid = Integer.parseInt(args[opti]);
15228                } catch (NumberFormatException e) {
15229                }
15230                synchronized (mProcessCpuTracker) {
15231                    final int N = mProcessCpuTracker.countStats();
15232                    for (int i=0; i<N; i++) {
15233                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15234                        if (st.pid == findPid || (st.baseName != null
15235                                && st.baseName.equals(args[opti]))) {
15236                            nativeProcs.add(st);
15237                        }
15238                    }
15239                }
15240                if (nativeProcs.size() > 0) {
15241                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15242                            isCompact);
15243                    Debug.MemoryInfo mi = null;
15244                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15245                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15246                        final int pid = r.pid;
15247                        if (!isCheckinRequest && dumpDetails) {
15248                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15249                        }
15250                        if (mi == null) {
15251                            mi = new Debug.MemoryInfo();
15252                        }
15253                        if (dumpDetails || (!brief && !oomOnly)) {
15254                            Debug.getMemoryInfo(pid, mi);
15255                        } else {
15256                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15257                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15258                        }
15259                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15260                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15261                        if (isCheckinRequest) {
15262                            pw.println();
15263                        }
15264                    }
15265                    return;
15266                }
15267            }
15268            pw.println("No process found for: " + args[opti]);
15269            return;
15270        }
15271
15272        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15273            dumpDetails = true;
15274        }
15275
15276        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15277
15278        String[] innerArgs = new String[args.length-opti];
15279        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15280
15281        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15282        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15283        long nativePss = 0;
15284        long nativeSwapPss = 0;
15285        long dalvikPss = 0;
15286        long dalvikSwapPss = 0;
15287        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15288                EmptyArray.LONG;
15289        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15290                EmptyArray.LONG;
15291        long otherPss = 0;
15292        long otherSwapPss = 0;
15293        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15294        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15295
15296        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15297        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15298        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15299                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15300
15301        long totalPss = 0;
15302        long totalSwapPss = 0;
15303        long cachedPss = 0;
15304        long cachedSwapPss = 0;
15305        boolean hasSwapPss = false;
15306
15307        Debug.MemoryInfo mi = null;
15308        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15309            final ProcessRecord r = procs.get(i);
15310            final IApplicationThread thread;
15311            final int pid;
15312            final int oomAdj;
15313            final boolean hasActivities;
15314            synchronized (this) {
15315                thread = r.thread;
15316                pid = r.pid;
15317                oomAdj = r.getSetAdjWithServices();
15318                hasActivities = r.activities.size() > 0;
15319            }
15320            if (thread != null) {
15321                if (!isCheckinRequest && dumpDetails) {
15322                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15323                }
15324                if (mi == null) {
15325                    mi = new Debug.MemoryInfo();
15326                }
15327                if (dumpDetails || (!brief && !oomOnly)) {
15328                    Debug.getMemoryInfo(pid, mi);
15329                    hasSwapPss = mi.hasSwappedOutPss;
15330                } else {
15331                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15332                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15333                }
15334                if (dumpDetails) {
15335                    if (localOnly) {
15336                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15337                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15338                        if (isCheckinRequest) {
15339                            pw.println();
15340                        }
15341                    } else {
15342                        try {
15343                            pw.flush();
15344                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15345                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15346                        } catch (RemoteException e) {
15347                            if (!isCheckinRequest) {
15348                                pw.println("Got RemoteException!");
15349                                pw.flush();
15350                            }
15351                        }
15352                    }
15353                }
15354
15355                final long myTotalPss = mi.getTotalPss();
15356                final long myTotalUss = mi.getTotalUss();
15357                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15358
15359                synchronized (this) {
15360                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15361                        // Record this for posterity if the process has been stable.
15362                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15363                    }
15364                }
15365
15366                if (!isCheckinRequest && mi != null) {
15367                    totalPss += myTotalPss;
15368                    totalSwapPss += myTotalSwapPss;
15369                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15370                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15371                            myTotalSwapPss, pid, hasActivities);
15372                    procMems.add(pssItem);
15373                    procMemsMap.put(pid, pssItem);
15374
15375                    nativePss += mi.nativePss;
15376                    nativeSwapPss += mi.nativeSwappedOutPss;
15377                    dalvikPss += mi.dalvikPss;
15378                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15379                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15380                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15381                        dalvikSubitemSwapPss[j] +=
15382                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15383                    }
15384                    otherPss += mi.otherPss;
15385                    otherSwapPss += mi.otherSwappedOutPss;
15386                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15387                        long mem = mi.getOtherPss(j);
15388                        miscPss[j] += mem;
15389                        otherPss -= mem;
15390                        mem = mi.getOtherSwappedOutPss(j);
15391                        miscSwapPss[j] += mem;
15392                        otherSwapPss -= mem;
15393                    }
15394
15395                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15396                        cachedPss += myTotalPss;
15397                        cachedSwapPss += myTotalSwapPss;
15398                    }
15399
15400                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15401                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15402                                || oomIndex == (oomPss.length-1)) {
15403                            oomPss[oomIndex] += myTotalPss;
15404                            oomSwapPss[oomIndex] += myTotalSwapPss;
15405                            if (oomProcs[oomIndex] == null) {
15406                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15407                            }
15408                            oomProcs[oomIndex].add(pssItem);
15409                            break;
15410                        }
15411                    }
15412                }
15413            }
15414        }
15415
15416        long nativeProcTotalPss = 0;
15417
15418        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15419            // If we are showing aggregations, also look for native processes to
15420            // include so that our aggregations are more accurate.
15421            updateCpuStatsNow();
15422            mi = null;
15423            synchronized (mProcessCpuTracker) {
15424                final int N = mProcessCpuTracker.countStats();
15425                for (int i=0; i<N; i++) {
15426                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15427                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15428                        if (mi == null) {
15429                            mi = new Debug.MemoryInfo();
15430                        }
15431                        if (!brief && !oomOnly) {
15432                            Debug.getMemoryInfo(st.pid, mi);
15433                        } else {
15434                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15435                            mi.nativePrivateDirty = (int)tmpLong[0];
15436                        }
15437
15438                        final long myTotalPss = mi.getTotalPss();
15439                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15440                        totalPss += myTotalPss;
15441                        nativeProcTotalPss += myTotalPss;
15442
15443                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15444                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15445                        procMems.add(pssItem);
15446
15447                        nativePss += mi.nativePss;
15448                        nativeSwapPss += mi.nativeSwappedOutPss;
15449                        dalvikPss += mi.dalvikPss;
15450                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15451                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15452                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15453                            dalvikSubitemSwapPss[j] +=
15454                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15455                        }
15456                        otherPss += mi.otherPss;
15457                        otherSwapPss += mi.otherSwappedOutPss;
15458                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15459                            long mem = mi.getOtherPss(j);
15460                            miscPss[j] += mem;
15461                            otherPss -= mem;
15462                            mem = mi.getOtherSwappedOutPss(j);
15463                            miscSwapPss[j] += mem;
15464                            otherSwapPss -= mem;
15465                        }
15466                        oomPss[0] += myTotalPss;
15467                        oomSwapPss[0] += myTotalSwapPss;
15468                        if (oomProcs[0] == null) {
15469                            oomProcs[0] = new ArrayList<MemItem>();
15470                        }
15471                        oomProcs[0].add(pssItem);
15472                    }
15473                }
15474            }
15475
15476            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15477
15478            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15479            final MemItem dalvikItem =
15480                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15481            if (dalvikSubitemPss.length > 0) {
15482                dalvikItem.subitems = new ArrayList<MemItem>();
15483                for (int j=0; j<dalvikSubitemPss.length; j++) {
15484                    final String name = Debug.MemoryInfo.getOtherLabel(
15485                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15486                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15487                                    dalvikSubitemSwapPss[j], j));
15488                }
15489            }
15490            catMems.add(dalvikItem);
15491            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15492            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15493                String label = Debug.MemoryInfo.getOtherLabel(j);
15494                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15495            }
15496
15497            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15498            for (int j=0; j<oomPss.length; j++) {
15499                if (oomPss[j] != 0) {
15500                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15501                            : DUMP_MEM_OOM_LABEL[j];
15502                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15503                            DUMP_MEM_OOM_ADJ[j]);
15504                    item.subitems = oomProcs[j];
15505                    oomMems.add(item);
15506                }
15507            }
15508
15509            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15510            if (!brief && !oomOnly && !isCompact) {
15511                pw.println();
15512                pw.println("Total PSS by process:");
15513                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15514                pw.println();
15515            }
15516            if (!isCompact) {
15517                pw.println("Total PSS by OOM adjustment:");
15518            }
15519            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15520            if (!brief && !oomOnly) {
15521                PrintWriter out = categoryPw != null ? categoryPw : pw;
15522                if (!isCompact) {
15523                    out.println();
15524                    out.println("Total PSS by category:");
15525                }
15526                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15527            }
15528            if (!isCompact) {
15529                pw.println();
15530            }
15531            MemInfoReader memInfo = new MemInfoReader();
15532            memInfo.readMemInfo();
15533            if (nativeProcTotalPss > 0) {
15534                synchronized (this) {
15535                    final long cachedKb = memInfo.getCachedSizeKb();
15536                    final long freeKb = memInfo.getFreeSizeKb();
15537                    final long zramKb = memInfo.getZramTotalSizeKb();
15538                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15539                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15540                            kernelKb*1024, nativeProcTotalPss*1024);
15541                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15542                            nativeProcTotalPss);
15543                }
15544            }
15545            if (!brief) {
15546                if (!isCompact) {
15547                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15548                    pw.print(" (status ");
15549                    switch (mLastMemoryLevel) {
15550                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15551                            pw.println("normal)");
15552                            break;
15553                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15554                            pw.println("moderate)");
15555                            break;
15556                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15557                            pw.println("low)");
15558                            break;
15559                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15560                            pw.println("critical)");
15561                            break;
15562                        default:
15563                            pw.print(mLastMemoryLevel);
15564                            pw.println(")");
15565                            break;
15566                    }
15567                    pw.print(" Free RAM: ");
15568                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15569                            + memInfo.getFreeSizeKb()));
15570                    pw.print(" (");
15571                    pw.print(stringifyKBSize(cachedPss));
15572                    pw.print(" cached pss + ");
15573                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15574                    pw.print(" cached kernel + ");
15575                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15576                    pw.println(" free)");
15577                } else {
15578                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15579                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15580                            + memInfo.getFreeSizeKb()); pw.print(",");
15581                    pw.println(totalPss - cachedPss);
15582                }
15583            }
15584            long lostRAM = memInfo.getTotalSizeKb()
15585                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15586                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15587            if (!isCompact) {
15588                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15589                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15590                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15591                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15592                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15593            } else {
15594                pw.print("lostram,"); pw.println(lostRAM);
15595            }
15596            if (!brief) {
15597                if (memInfo.getZramTotalSizeKb() != 0) {
15598                    if (!isCompact) {
15599                        pw.print("     ZRAM: ");
15600                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15601                                pw.print(" physical used for ");
15602                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15603                                        - memInfo.getSwapFreeSizeKb()));
15604                                pw.print(" in swap (");
15605                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15606                                pw.println(" total swap)");
15607                    } else {
15608                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15609                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15610                                pw.println(memInfo.getSwapFreeSizeKb());
15611                    }
15612                }
15613                final long[] ksm = getKsmInfo();
15614                if (!isCompact) {
15615                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15616                            || ksm[KSM_VOLATILE] != 0) {
15617                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15618                                pw.print(" saved from shared ");
15619                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15620                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15621                                pw.print(" unshared; ");
15622                                pw.print(stringifyKBSize(
15623                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15624                    }
15625                    pw.print("   Tuning: ");
15626                    pw.print(ActivityManager.staticGetMemoryClass());
15627                    pw.print(" (large ");
15628                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15629                    pw.print("), oom ");
15630                    pw.print(stringifySize(
15631                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15632                    pw.print(", restore limit ");
15633                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15634                    if (ActivityManager.isLowRamDeviceStatic()) {
15635                        pw.print(" (low-ram)");
15636                    }
15637                    if (ActivityManager.isHighEndGfx()) {
15638                        pw.print(" (high-end-gfx)");
15639                    }
15640                    pw.println();
15641                } else {
15642                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15643                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15644                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15645                    pw.print("tuning,");
15646                    pw.print(ActivityManager.staticGetMemoryClass());
15647                    pw.print(',');
15648                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15649                    pw.print(',');
15650                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15651                    if (ActivityManager.isLowRamDeviceStatic()) {
15652                        pw.print(",low-ram");
15653                    }
15654                    if (ActivityManager.isHighEndGfx()) {
15655                        pw.print(",high-end-gfx");
15656                    }
15657                    pw.println();
15658                }
15659            }
15660        }
15661    }
15662
15663    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15664            long memtrack, String name) {
15665        sb.append("  ");
15666        sb.append(ProcessList.makeOomAdjString(oomAdj));
15667        sb.append(' ');
15668        sb.append(ProcessList.makeProcStateString(procState));
15669        sb.append(' ');
15670        ProcessList.appendRamKb(sb, pss);
15671        sb.append(": ");
15672        sb.append(name);
15673        if (memtrack > 0) {
15674            sb.append(" (");
15675            sb.append(stringifyKBSize(memtrack));
15676            sb.append(" memtrack)");
15677        }
15678    }
15679
15680    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15681        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15682        sb.append(" (pid ");
15683        sb.append(mi.pid);
15684        sb.append(") ");
15685        sb.append(mi.adjType);
15686        sb.append('\n');
15687        if (mi.adjReason != null) {
15688            sb.append("                      ");
15689            sb.append(mi.adjReason);
15690            sb.append('\n');
15691        }
15692    }
15693
15694    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15695        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15696        for (int i=0, N=memInfos.size(); i<N; i++) {
15697            ProcessMemInfo mi = memInfos.get(i);
15698            infoMap.put(mi.pid, mi);
15699        }
15700        updateCpuStatsNow();
15701        long[] memtrackTmp = new long[1];
15702        synchronized (mProcessCpuTracker) {
15703            final int N = mProcessCpuTracker.countStats();
15704            for (int i=0; i<N; i++) {
15705                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15706                if (st.vsize > 0) {
15707                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15708                    if (pss > 0) {
15709                        if (infoMap.indexOfKey(st.pid) < 0) {
15710                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15711                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15712                            mi.pss = pss;
15713                            mi.memtrack = memtrackTmp[0];
15714                            memInfos.add(mi);
15715                        }
15716                    }
15717                }
15718            }
15719        }
15720
15721        long totalPss = 0;
15722        long totalMemtrack = 0;
15723        for (int i=0, N=memInfos.size(); i<N; i++) {
15724            ProcessMemInfo mi = memInfos.get(i);
15725            if (mi.pss == 0) {
15726                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15727                mi.memtrack = memtrackTmp[0];
15728            }
15729            totalPss += mi.pss;
15730            totalMemtrack += mi.memtrack;
15731        }
15732        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15733            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15734                if (lhs.oomAdj != rhs.oomAdj) {
15735                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15736                }
15737                if (lhs.pss != rhs.pss) {
15738                    return lhs.pss < rhs.pss ? 1 : -1;
15739                }
15740                return 0;
15741            }
15742        });
15743
15744        StringBuilder tag = new StringBuilder(128);
15745        StringBuilder stack = new StringBuilder(128);
15746        tag.append("Low on memory -- ");
15747        appendMemBucket(tag, totalPss, "total", false);
15748        appendMemBucket(stack, totalPss, "total", true);
15749
15750        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15751        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15752        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15753
15754        boolean firstLine = true;
15755        int lastOomAdj = Integer.MIN_VALUE;
15756        long extraNativeRam = 0;
15757        long extraNativeMemtrack = 0;
15758        long cachedPss = 0;
15759        for (int i=0, N=memInfos.size(); i<N; i++) {
15760            ProcessMemInfo mi = memInfos.get(i);
15761
15762            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15763                cachedPss += mi.pss;
15764            }
15765
15766            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15767                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15768                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15769                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15770                if (lastOomAdj != mi.oomAdj) {
15771                    lastOomAdj = mi.oomAdj;
15772                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15773                        tag.append(" / ");
15774                    }
15775                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15776                        if (firstLine) {
15777                            stack.append(":");
15778                            firstLine = false;
15779                        }
15780                        stack.append("\n\t at ");
15781                    } else {
15782                        stack.append("$");
15783                    }
15784                } else {
15785                    tag.append(" ");
15786                    stack.append("$");
15787                }
15788                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15789                    appendMemBucket(tag, mi.pss, mi.name, false);
15790                }
15791                appendMemBucket(stack, mi.pss, mi.name, true);
15792                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15793                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15794                    stack.append("(");
15795                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15796                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15797                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15798                            stack.append(":");
15799                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15800                        }
15801                    }
15802                    stack.append(")");
15803                }
15804            }
15805
15806            appendMemInfo(fullNativeBuilder, mi);
15807            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15808                // The short form only has native processes that are >= 512K.
15809                if (mi.pss >= 512) {
15810                    appendMemInfo(shortNativeBuilder, mi);
15811                } else {
15812                    extraNativeRam += mi.pss;
15813                    extraNativeMemtrack += mi.memtrack;
15814                }
15815            } else {
15816                // Short form has all other details, but if we have collected RAM
15817                // from smaller native processes let's dump a summary of that.
15818                if (extraNativeRam > 0) {
15819                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15820                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15821                    shortNativeBuilder.append('\n');
15822                    extraNativeRam = 0;
15823                }
15824                appendMemInfo(fullJavaBuilder, mi);
15825            }
15826        }
15827
15828        fullJavaBuilder.append("           ");
15829        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15830        fullJavaBuilder.append(": TOTAL");
15831        if (totalMemtrack > 0) {
15832            fullJavaBuilder.append(" (");
15833            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15834            fullJavaBuilder.append(" memtrack)");
15835        } else {
15836        }
15837        fullJavaBuilder.append("\n");
15838
15839        MemInfoReader memInfo = new MemInfoReader();
15840        memInfo.readMemInfo();
15841        final long[] infos = memInfo.getRawInfo();
15842
15843        StringBuilder memInfoBuilder = new StringBuilder(1024);
15844        Debug.getMemInfo(infos);
15845        memInfoBuilder.append("  MemInfo: ");
15846        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15847        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15848        memInfoBuilder.append(stringifyKBSize(
15849                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15850        memInfoBuilder.append(stringifyKBSize(
15851                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15852        memInfoBuilder.append(stringifyKBSize(
15853                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15854        memInfoBuilder.append("           ");
15855        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15856        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15857        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15858        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15859        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15860            memInfoBuilder.append("  ZRAM: ");
15861            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15862            memInfoBuilder.append(" RAM, ");
15863            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15864            memInfoBuilder.append(" swap total, ");
15865            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15866            memInfoBuilder.append(" swap free\n");
15867        }
15868        final long[] ksm = getKsmInfo();
15869        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15870                || ksm[KSM_VOLATILE] != 0) {
15871            memInfoBuilder.append("  KSM: ");
15872            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15873            memInfoBuilder.append(" saved from shared ");
15874            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15875            memInfoBuilder.append("\n       ");
15876            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15877            memInfoBuilder.append(" unshared; ");
15878            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15879            memInfoBuilder.append(" volatile\n");
15880        }
15881        memInfoBuilder.append("  Free RAM: ");
15882        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15883                + memInfo.getFreeSizeKb()));
15884        memInfoBuilder.append("\n");
15885        memInfoBuilder.append("  Used RAM: ");
15886        memInfoBuilder.append(stringifyKBSize(
15887                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15888        memInfoBuilder.append("\n");
15889        memInfoBuilder.append("  Lost RAM: ");
15890        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15891                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15892                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15893        memInfoBuilder.append("\n");
15894        Slog.i(TAG, "Low on memory:");
15895        Slog.i(TAG, shortNativeBuilder.toString());
15896        Slog.i(TAG, fullJavaBuilder.toString());
15897        Slog.i(TAG, memInfoBuilder.toString());
15898
15899        StringBuilder dropBuilder = new StringBuilder(1024);
15900        /*
15901        StringWriter oomSw = new StringWriter();
15902        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15903        StringWriter catSw = new StringWriter();
15904        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15905        String[] emptyArgs = new String[] { };
15906        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15907        oomPw.flush();
15908        String oomString = oomSw.toString();
15909        */
15910        dropBuilder.append("Low on memory:");
15911        dropBuilder.append(stack);
15912        dropBuilder.append('\n');
15913        dropBuilder.append(fullNativeBuilder);
15914        dropBuilder.append(fullJavaBuilder);
15915        dropBuilder.append('\n');
15916        dropBuilder.append(memInfoBuilder);
15917        dropBuilder.append('\n');
15918        /*
15919        dropBuilder.append(oomString);
15920        dropBuilder.append('\n');
15921        */
15922        StringWriter catSw = new StringWriter();
15923        synchronized (ActivityManagerService.this) {
15924            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15925            String[] emptyArgs = new String[] { };
15926            catPw.println();
15927            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15928            catPw.println();
15929            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15930                    false, false, null);
15931            catPw.println();
15932            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15933            catPw.flush();
15934        }
15935        dropBuilder.append(catSw.toString());
15936        addErrorToDropBox("lowmem", null, "system_server", null,
15937                null, tag.toString(), dropBuilder.toString(), null, null);
15938        //Slog.i(TAG, "Sent to dropbox:");
15939        //Slog.i(TAG, dropBuilder.toString());
15940        synchronized (ActivityManagerService.this) {
15941            long now = SystemClock.uptimeMillis();
15942            if (mLastMemUsageReportTime < now) {
15943                mLastMemUsageReportTime = now;
15944            }
15945        }
15946    }
15947
15948    /**
15949     * Searches array of arguments for the specified string
15950     * @param args array of argument strings
15951     * @param value value to search for
15952     * @return true if the value is contained in the array
15953     */
15954    private static boolean scanArgs(String[] args, String value) {
15955        if (args != null) {
15956            for (String arg : args) {
15957                if (value.equals(arg)) {
15958                    return true;
15959                }
15960            }
15961        }
15962        return false;
15963    }
15964
15965    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15966            ContentProviderRecord cpr, boolean always) {
15967        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15968
15969        if (!inLaunching || always) {
15970            synchronized (cpr) {
15971                cpr.launchingApp = null;
15972                cpr.notifyAll();
15973            }
15974            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15975            String names[] = cpr.info.authority.split(";");
15976            for (int j = 0; j < names.length; j++) {
15977                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15978            }
15979        }
15980
15981        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15982            ContentProviderConnection conn = cpr.connections.get(i);
15983            if (conn.waiting) {
15984                // If this connection is waiting for the provider, then we don't
15985                // need to mess with its process unless we are always removing
15986                // or for some reason the provider is not currently launching.
15987                if (inLaunching && !always) {
15988                    continue;
15989                }
15990            }
15991            ProcessRecord capp = conn.client;
15992            conn.dead = true;
15993            if (conn.stableCount > 0) {
15994                if (!capp.persistent && capp.thread != null
15995                        && capp.pid != 0
15996                        && capp.pid != MY_PID) {
15997                    capp.kill("depends on provider "
15998                            + cpr.name.flattenToShortString()
15999                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16000                }
16001            } else if (capp.thread != null && conn.provider.provider != null) {
16002                try {
16003                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16004                } catch (RemoteException e) {
16005                }
16006                // In the protocol here, we don't expect the client to correctly
16007                // clean up this connection, we'll just remove it.
16008                cpr.connections.remove(i);
16009                if (conn.client.conProviders.remove(conn)) {
16010                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16011                }
16012            }
16013        }
16014
16015        if (inLaunching && always) {
16016            mLaunchingProviders.remove(cpr);
16017        }
16018        return inLaunching;
16019    }
16020
16021    /**
16022     * Main code for cleaning up a process when it has gone away.  This is
16023     * called both as a result of the process dying, or directly when stopping
16024     * a process when running in single process mode.
16025     *
16026     * @return Returns true if the given process has been restarted, so the
16027     * app that was passed in must remain on the process lists.
16028     */
16029    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16030            boolean restarting, boolean allowRestart, int index) {
16031        if (index >= 0) {
16032            removeLruProcessLocked(app);
16033            ProcessList.remove(app.pid);
16034        }
16035
16036        mProcessesToGc.remove(app);
16037        mPendingPssProcesses.remove(app);
16038
16039        // Dismiss any open dialogs.
16040        if (app.crashDialog != null && !app.forceCrashReport) {
16041            app.crashDialog.dismiss();
16042            app.crashDialog = null;
16043        }
16044        if (app.anrDialog != null) {
16045            app.anrDialog.dismiss();
16046            app.anrDialog = null;
16047        }
16048        if (app.waitDialog != null) {
16049            app.waitDialog.dismiss();
16050            app.waitDialog = null;
16051        }
16052
16053        app.crashing = false;
16054        app.notResponding = false;
16055
16056        app.resetPackageList(mProcessStats);
16057        app.unlinkDeathRecipient();
16058        app.makeInactive(mProcessStats);
16059        app.waitingToKill = null;
16060        app.forcingToForeground = null;
16061        updateProcessForegroundLocked(app, false, false);
16062        app.foregroundActivities = false;
16063        app.hasShownUi = false;
16064        app.treatLikeActivity = false;
16065        app.hasAboveClient = false;
16066        app.hasClientActivities = false;
16067
16068        mServices.killServicesLocked(app, allowRestart);
16069
16070        boolean restart = false;
16071
16072        // Remove published content providers.
16073        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16074            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16075            final boolean always = app.bad || !allowRestart;
16076            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16077            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16078                // We left the provider in the launching list, need to
16079                // restart it.
16080                restart = true;
16081            }
16082
16083            cpr.provider = null;
16084            cpr.proc = null;
16085        }
16086        app.pubProviders.clear();
16087
16088        // Take care of any launching providers waiting for this process.
16089        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16090            restart = true;
16091        }
16092
16093        // Unregister from connected content providers.
16094        if (!app.conProviders.isEmpty()) {
16095            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16096                ContentProviderConnection conn = app.conProviders.get(i);
16097                conn.provider.connections.remove(conn);
16098                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16099                        conn.provider.name);
16100            }
16101            app.conProviders.clear();
16102        }
16103
16104        // At this point there may be remaining entries in mLaunchingProviders
16105        // where we were the only one waiting, so they are no longer of use.
16106        // Look for these and clean up if found.
16107        // XXX Commented out for now.  Trying to figure out a way to reproduce
16108        // the actual situation to identify what is actually going on.
16109        if (false) {
16110            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16111                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16112                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16113                    synchronized (cpr) {
16114                        cpr.launchingApp = null;
16115                        cpr.notifyAll();
16116                    }
16117                }
16118            }
16119        }
16120
16121        skipCurrentReceiverLocked(app);
16122
16123        // Unregister any receivers.
16124        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16125            removeReceiverLocked(app.receivers.valueAt(i));
16126        }
16127        app.receivers.clear();
16128
16129        // If the app is undergoing backup, tell the backup manager about it
16130        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16131            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16132                    + mBackupTarget.appInfo + " died during backup");
16133            try {
16134                IBackupManager bm = IBackupManager.Stub.asInterface(
16135                        ServiceManager.getService(Context.BACKUP_SERVICE));
16136                bm.agentDisconnected(app.info.packageName);
16137            } catch (RemoteException e) {
16138                // can't happen; backup manager is local
16139            }
16140        }
16141
16142        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16143            ProcessChangeItem item = mPendingProcessChanges.get(i);
16144            if (item.pid == app.pid) {
16145                mPendingProcessChanges.remove(i);
16146                mAvailProcessChanges.add(item);
16147            }
16148        }
16149        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16150                null).sendToTarget();
16151
16152        // If the caller is restarting this app, then leave it in its
16153        // current lists and let the caller take care of it.
16154        if (restarting) {
16155            return false;
16156        }
16157
16158        if (!app.persistent || app.isolated) {
16159            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16160                    "Removing non-persistent process during cleanup: " + app);
16161            removeProcessNameLocked(app.processName, app.uid);
16162            if (mHeavyWeightProcess == app) {
16163                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16164                        mHeavyWeightProcess.userId, 0));
16165                mHeavyWeightProcess = null;
16166            }
16167        } else if (!app.removed) {
16168            // This app is persistent, so we need to keep its record around.
16169            // If it is not already on the pending app list, add it there
16170            // and start a new process for it.
16171            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16172                mPersistentStartingProcesses.add(app);
16173                restart = true;
16174            }
16175        }
16176        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16177                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16178        mProcessesOnHold.remove(app);
16179
16180        if (app == mHomeProcess) {
16181            mHomeProcess = null;
16182        }
16183        if (app == mPreviousProcess) {
16184            mPreviousProcess = null;
16185        }
16186
16187        if (restart && !app.isolated) {
16188            // We have components that still need to be running in the
16189            // process, so re-launch it.
16190            if (index < 0) {
16191                ProcessList.remove(app.pid);
16192            }
16193            addProcessNameLocked(app);
16194            startProcessLocked(app, "restart", app.processName);
16195            return true;
16196        } else if (app.pid > 0 && app.pid != MY_PID) {
16197            // Goodbye!
16198            boolean removed;
16199            synchronized (mPidsSelfLocked) {
16200                mPidsSelfLocked.remove(app.pid);
16201                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16202            }
16203            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16204            if (app.isolated) {
16205                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16206            }
16207            app.setPid(0);
16208        }
16209        return false;
16210    }
16211
16212    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16213        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16214            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16215            if (cpr.launchingApp == app) {
16216                return true;
16217            }
16218        }
16219        return false;
16220    }
16221
16222    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16223        // Look through the content providers we are waiting to have launched,
16224        // and if any run in this process then either schedule a restart of
16225        // the process or kill the client waiting for it if this process has
16226        // gone bad.
16227        boolean restart = false;
16228        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16229            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16230            if (cpr.launchingApp == app) {
16231                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16232                    restart = true;
16233                } else {
16234                    removeDyingProviderLocked(app, cpr, true);
16235                }
16236            }
16237        }
16238        return restart;
16239    }
16240
16241    // =========================================================
16242    // SERVICES
16243    // =========================================================
16244
16245    @Override
16246    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16247            int flags) {
16248        enforceNotIsolatedCaller("getServices");
16249        synchronized (this) {
16250            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16251        }
16252    }
16253
16254    @Override
16255    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16256        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16257        synchronized (this) {
16258            return mServices.getRunningServiceControlPanelLocked(name);
16259        }
16260    }
16261
16262    @Override
16263    public ComponentName startService(IApplicationThread caller, Intent service,
16264            String resolvedType, String callingPackage, int userId)
16265            throws TransactionTooLargeException {
16266        enforceNotIsolatedCaller("startService");
16267        // Refuse possible leaked file descriptors
16268        if (service != null && service.hasFileDescriptors() == true) {
16269            throw new IllegalArgumentException("File descriptors passed in Intent");
16270        }
16271
16272        if (callingPackage == null) {
16273            throw new IllegalArgumentException("callingPackage cannot be null");
16274        }
16275
16276        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16277                "startService: " + service + " type=" + resolvedType);
16278        synchronized(this) {
16279            final int callingPid = Binder.getCallingPid();
16280            final int callingUid = Binder.getCallingUid();
16281            final long origId = Binder.clearCallingIdentity();
16282            ComponentName res = mServices.startServiceLocked(caller, service,
16283                    resolvedType, callingPid, callingUid, callingPackage, userId);
16284            Binder.restoreCallingIdentity(origId);
16285            return res;
16286        }
16287    }
16288
16289    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16290            String callingPackage, int userId)
16291            throws TransactionTooLargeException {
16292        synchronized(this) {
16293            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16294                    "startServiceInPackage: " + service + " type=" + resolvedType);
16295            final long origId = Binder.clearCallingIdentity();
16296            ComponentName res = mServices.startServiceLocked(null, service,
16297                    resolvedType, -1, uid, callingPackage, userId);
16298            Binder.restoreCallingIdentity(origId);
16299            return res;
16300        }
16301    }
16302
16303    @Override
16304    public int stopService(IApplicationThread caller, Intent service,
16305            String resolvedType, int userId) {
16306        enforceNotIsolatedCaller("stopService");
16307        // Refuse possible leaked file descriptors
16308        if (service != null && service.hasFileDescriptors() == true) {
16309            throw new IllegalArgumentException("File descriptors passed in Intent");
16310        }
16311
16312        synchronized(this) {
16313            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16314        }
16315    }
16316
16317    @Override
16318    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16319        enforceNotIsolatedCaller("peekService");
16320        // Refuse possible leaked file descriptors
16321        if (service != null && service.hasFileDescriptors() == true) {
16322            throw new IllegalArgumentException("File descriptors passed in Intent");
16323        }
16324
16325        if (callingPackage == null) {
16326            throw new IllegalArgumentException("callingPackage cannot be null");
16327        }
16328
16329        synchronized(this) {
16330            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16331        }
16332    }
16333
16334    @Override
16335    public boolean stopServiceToken(ComponentName className, IBinder token,
16336            int startId) {
16337        synchronized(this) {
16338            return mServices.stopServiceTokenLocked(className, token, startId);
16339        }
16340    }
16341
16342    @Override
16343    public void setServiceForeground(ComponentName className, IBinder token,
16344            int id, Notification notification, boolean removeNotification) {
16345        synchronized(this) {
16346            mServices.setServiceForegroundLocked(className, token, id, notification,
16347                    removeNotification);
16348        }
16349    }
16350
16351    @Override
16352    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16353            boolean requireFull, String name, String callerPackage) {
16354        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16355                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16356    }
16357
16358    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16359            String className, int flags) {
16360        boolean result = false;
16361        // For apps that don't have pre-defined UIDs, check for permission
16362        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16363            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16364                if (ActivityManager.checkUidPermission(
16365                        INTERACT_ACROSS_USERS,
16366                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16367                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16368                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16369                            + " requests FLAG_SINGLE_USER, but app does not hold "
16370                            + INTERACT_ACROSS_USERS;
16371                    Slog.w(TAG, msg);
16372                    throw new SecurityException(msg);
16373                }
16374                // Permission passed
16375                result = true;
16376            }
16377        } else if ("system".equals(componentProcessName)) {
16378            result = true;
16379        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16380            // Phone app and persistent apps are allowed to export singleuser providers.
16381            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16382                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16383        }
16384        if (DEBUG_MU) Slog.v(TAG_MU,
16385                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16386                + Integer.toHexString(flags) + ") = " + result);
16387        return result;
16388    }
16389
16390    /**
16391     * Checks to see if the caller is in the same app as the singleton
16392     * component, or the component is in a special app. It allows special apps
16393     * to export singleton components but prevents exporting singleton
16394     * components for regular apps.
16395     */
16396    boolean isValidSingletonCall(int callingUid, int componentUid) {
16397        int componentAppId = UserHandle.getAppId(componentUid);
16398        return UserHandle.isSameApp(callingUid, componentUid)
16399                || componentAppId == Process.SYSTEM_UID
16400                || componentAppId == Process.PHONE_UID
16401                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16402                        == PackageManager.PERMISSION_GRANTED;
16403    }
16404
16405    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16406            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16407            int userId) throws TransactionTooLargeException {
16408        enforceNotIsolatedCaller("bindService");
16409
16410        // Refuse possible leaked file descriptors
16411        if (service != null && service.hasFileDescriptors() == true) {
16412            throw new IllegalArgumentException("File descriptors passed in Intent");
16413        }
16414
16415        if (callingPackage == null) {
16416            throw new IllegalArgumentException("callingPackage cannot be null");
16417        }
16418
16419        synchronized(this) {
16420            return mServices.bindServiceLocked(caller, token, service,
16421                    resolvedType, connection, flags, callingPackage, userId);
16422        }
16423    }
16424
16425    public boolean unbindService(IServiceConnection connection) {
16426        synchronized (this) {
16427            return mServices.unbindServiceLocked(connection);
16428        }
16429    }
16430
16431    public void publishService(IBinder token, Intent intent, IBinder service) {
16432        // Refuse possible leaked file descriptors
16433        if (intent != null && intent.hasFileDescriptors() == true) {
16434            throw new IllegalArgumentException("File descriptors passed in Intent");
16435        }
16436
16437        synchronized(this) {
16438            if (!(token instanceof ServiceRecord)) {
16439                throw new IllegalArgumentException("Invalid service token");
16440            }
16441            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16442        }
16443    }
16444
16445    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16446        // Refuse possible leaked file descriptors
16447        if (intent != null && intent.hasFileDescriptors() == true) {
16448            throw new IllegalArgumentException("File descriptors passed in Intent");
16449        }
16450
16451        synchronized(this) {
16452            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16453        }
16454    }
16455
16456    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16457        synchronized(this) {
16458            if (!(token instanceof ServiceRecord)) {
16459                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16460                throw new IllegalArgumentException("Invalid service token");
16461            }
16462            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16463        }
16464    }
16465
16466    // =========================================================
16467    // BACKUP AND RESTORE
16468    // =========================================================
16469
16470    // Cause the target app to be launched if necessary and its backup agent
16471    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16472    // activity manager to announce its creation.
16473    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16474        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16475                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16476        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16477
16478        synchronized(this) {
16479            // !!! TODO: currently no check here that we're already bound
16480            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16481            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16482            synchronized (stats) {
16483                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16484            }
16485
16486            // Backup agent is now in use, its package can't be stopped.
16487            try {
16488                AppGlobals.getPackageManager().setPackageStoppedState(
16489                        app.packageName, false, UserHandle.getUserId(app.uid));
16490            } catch (RemoteException e) {
16491            } catch (IllegalArgumentException e) {
16492                Slog.w(TAG, "Failed trying to unstop package "
16493                        + app.packageName + ": " + e);
16494            }
16495
16496            BackupRecord r = new BackupRecord(ss, app, backupMode);
16497            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16498                    ? new ComponentName(app.packageName, app.backupAgentName)
16499                    : new ComponentName("android", "FullBackupAgent");
16500            // startProcessLocked() returns existing proc's record if it's already running
16501            ProcessRecord proc = startProcessLocked(app.processName, app,
16502                    false, 0, "backup", hostingName, false, false, false);
16503            if (proc == null) {
16504                Slog.e(TAG, "Unable to start backup agent process " + r);
16505                return false;
16506            }
16507
16508            r.app = proc;
16509            mBackupTarget = r;
16510            mBackupAppName = app.packageName;
16511
16512            // Try not to kill the process during backup
16513            updateOomAdjLocked(proc);
16514
16515            // If the process is already attached, schedule the creation of the backup agent now.
16516            // If it is not yet live, this will be done when it attaches to the framework.
16517            if (proc.thread != null) {
16518                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16519                try {
16520                    proc.thread.scheduleCreateBackupAgent(app,
16521                            compatibilityInfoForPackageLocked(app), backupMode);
16522                } catch (RemoteException e) {
16523                    // Will time out on the backup manager side
16524                }
16525            } else {
16526                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16527            }
16528            // Invariants: at this point, the target app process exists and the application
16529            // is either already running or in the process of coming up.  mBackupTarget and
16530            // mBackupAppName describe the app, so that when it binds back to the AM we
16531            // know that it's scheduled for a backup-agent operation.
16532        }
16533
16534        return true;
16535    }
16536
16537    @Override
16538    public void clearPendingBackup() {
16539        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16540        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16541
16542        synchronized (this) {
16543            mBackupTarget = null;
16544            mBackupAppName = null;
16545        }
16546    }
16547
16548    // A backup agent has just come up
16549    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16550        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16551                + " = " + agent);
16552
16553        synchronized(this) {
16554            if (!agentPackageName.equals(mBackupAppName)) {
16555                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16556                return;
16557            }
16558        }
16559
16560        long oldIdent = Binder.clearCallingIdentity();
16561        try {
16562            IBackupManager bm = IBackupManager.Stub.asInterface(
16563                    ServiceManager.getService(Context.BACKUP_SERVICE));
16564            bm.agentConnected(agentPackageName, agent);
16565        } catch (RemoteException e) {
16566            // can't happen; the backup manager service is local
16567        } catch (Exception e) {
16568            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16569            e.printStackTrace();
16570        } finally {
16571            Binder.restoreCallingIdentity(oldIdent);
16572        }
16573    }
16574
16575    // done with this agent
16576    public void unbindBackupAgent(ApplicationInfo appInfo) {
16577        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16578        if (appInfo == null) {
16579            Slog.w(TAG, "unbind backup agent for null app");
16580            return;
16581        }
16582
16583        synchronized(this) {
16584            try {
16585                if (mBackupAppName == null) {
16586                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16587                    return;
16588                }
16589
16590                if (!mBackupAppName.equals(appInfo.packageName)) {
16591                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16592                    return;
16593                }
16594
16595                // Not backing this app up any more; reset its OOM adjustment
16596                final ProcessRecord proc = mBackupTarget.app;
16597                updateOomAdjLocked(proc);
16598
16599                // If the app crashed during backup, 'thread' will be null here
16600                if (proc.thread != null) {
16601                    try {
16602                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16603                                compatibilityInfoForPackageLocked(appInfo));
16604                    } catch (Exception e) {
16605                        Slog.e(TAG, "Exception when unbinding backup agent:");
16606                        e.printStackTrace();
16607                    }
16608                }
16609            } finally {
16610                mBackupTarget = null;
16611                mBackupAppName = null;
16612            }
16613        }
16614    }
16615    // =========================================================
16616    // BROADCASTS
16617    // =========================================================
16618
16619    boolean isPendingBroadcastProcessLocked(int pid) {
16620        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16621                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16622    }
16623
16624    void skipPendingBroadcastLocked(int pid) {
16625            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16626            for (BroadcastQueue queue : mBroadcastQueues) {
16627                queue.skipPendingBroadcastLocked(pid);
16628            }
16629    }
16630
16631    // The app just attached; send any pending broadcasts that it should receive
16632    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16633        boolean didSomething = false;
16634        for (BroadcastQueue queue : mBroadcastQueues) {
16635            didSomething |= queue.sendPendingBroadcastsLocked(app);
16636        }
16637        return didSomething;
16638    }
16639
16640    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16641            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16642        enforceNotIsolatedCaller("registerReceiver");
16643        ArrayList<Intent> stickyIntents = null;
16644        ProcessRecord callerApp = null;
16645        int callingUid;
16646        int callingPid;
16647        synchronized(this) {
16648            if (caller != null) {
16649                callerApp = getRecordForAppLocked(caller);
16650                if (callerApp == null) {
16651                    throw new SecurityException(
16652                            "Unable to find app for caller " + caller
16653                            + " (pid=" + Binder.getCallingPid()
16654                            + ") when registering receiver " + receiver);
16655                }
16656                if (callerApp.info.uid != Process.SYSTEM_UID &&
16657                        !callerApp.pkgList.containsKey(callerPackage) &&
16658                        !"android".equals(callerPackage)) {
16659                    throw new SecurityException("Given caller package " + callerPackage
16660                            + " is not running in process " + callerApp);
16661                }
16662                callingUid = callerApp.info.uid;
16663                callingPid = callerApp.pid;
16664            } else {
16665                callerPackage = null;
16666                callingUid = Binder.getCallingUid();
16667                callingPid = Binder.getCallingPid();
16668            }
16669
16670            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16671                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16672
16673            Iterator<String> actions = filter.actionsIterator();
16674            if (actions == null) {
16675                ArrayList<String> noAction = new ArrayList<String>(1);
16676                noAction.add(null);
16677                actions = noAction.iterator();
16678            }
16679
16680            // Collect stickies of users
16681            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16682            while (actions.hasNext()) {
16683                String action = actions.next();
16684                for (int id : userIds) {
16685                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16686                    if (stickies != null) {
16687                        ArrayList<Intent> intents = stickies.get(action);
16688                        if (intents != null) {
16689                            if (stickyIntents == null) {
16690                                stickyIntents = new ArrayList<Intent>();
16691                            }
16692                            stickyIntents.addAll(intents);
16693                        }
16694                    }
16695                }
16696            }
16697        }
16698
16699        ArrayList<Intent> allSticky = null;
16700        if (stickyIntents != null) {
16701            final ContentResolver resolver = mContext.getContentResolver();
16702            // Look for any matching sticky broadcasts...
16703            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16704                Intent intent = stickyIntents.get(i);
16705                // If intent has scheme "content", it will need to acccess
16706                // provider that needs to lock mProviderMap in ActivityThread
16707                // and also it may need to wait application response, so we
16708                // cannot lock ActivityManagerService here.
16709                if (filter.match(resolver, intent, true, TAG) >= 0) {
16710                    if (allSticky == null) {
16711                        allSticky = new ArrayList<Intent>();
16712                    }
16713                    allSticky.add(intent);
16714                }
16715            }
16716        }
16717
16718        // The first sticky in the list is returned directly back to the client.
16719        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16720        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16721        if (receiver == null) {
16722            return sticky;
16723        }
16724
16725        synchronized (this) {
16726            if (callerApp != null && (callerApp.thread == null
16727                    || callerApp.thread.asBinder() != caller.asBinder())) {
16728                // Original caller already died
16729                return null;
16730            }
16731            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16732            if (rl == null) {
16733                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16734                        userId, receiver);
16735                if (rl.app != null) {
16736                    rl.app.receivers.add(rl);
16737                } else {
16738                    try {
16739                        receiver.asBinder().linkToDeath(rl, 0);
16740                    } catch (RemoteException e) {
16741                        return sticky;
16742                    }
16743                    rl.linkedToDeath = true;
16744                }
16745                mRegisteredReceivers.put(receiver.asBinder(), rl);
16746            } else if (rl.uid != callingUid) {
16747                throw new IllegalArgumentException(
16748                        "Receiver requested to register for uid " + callingUid
16749                        + " was previously registered for uid " + rl.uid);
16750            } else if (rl.pid != callingPid) {
16751                throw new IllegalArgumentException(
16752                        "Receiver requested to register for pid " + callingPid
16753                        + " was previously registered for pid " + rl.pid);
16754            } else if (rl.userId != userId) {
16755                throw new IllegalArgumentException(
16756                        "Receiver requested to register for user " + userId
16757                        + " was previously registered for user " + rl.userId);
16758            }
16759            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16760                    permission, callingUid, userId);
16761            rl.add(bf);
16762            if (!bf.debugCheck()) {
16763                Slog.w(TAG, "==> For Dynamic broadcast");
16764            }
16765            mReceiverResolver.addFilter(bf);
16766
16767            // Enqueue broadcasts for all existing stickies that match
16768            // this filter.
16769            if (allSticky != null) {
16770                ArrayList receivers = new ArrayList();
16771                receivers.add(bf);
16772
16773                final int stickyCount = allSticky.size();
16774                for (int i = 0; i < stickyCount; i++) {
16775                    Intent intent = allSticky.get(i);
16776                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16777                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16778                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16779                            null, 0, null, null, false, true, true, -1);
16780                    queue.enqueueParallelBroadcastLocked(r);
16781                    queue.scheduleBroadcastsLocked();
16782                }
16783            }
16784
16785            return sticky;
16786        }
16787    }
16788
16789    public void unregisterReceiver(IIntentReceiver receiver) {
16790        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16791
16792        final long origId = Binder.clearCallingIdentity();
16793        try {
16794            boolean doTrim = false;
16795
16796            synchronized(this) {
16797                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16798                if (rl != null) {
16799                    final BroadcastRecord r = rl.curBroadcast;
16800                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16801                        final boolean doNext = r.queue.finishReceiverLocked(
16802                                r, r.resultCode, r.resultData, r.resultExtras,
16803                                r.resultAbort, false);
16804                        if (doNext) {
16805                            doTrim = true;
16806                            r.queue.processNextBroadcast(false);
16807                        }
16808                    }
16809
16810                    if (rl.app != null) {
16811                        rl.app.receivers.remove(rl);
16812                    }
16813                    removeReceiverLocked(rl);
16814                    if (rl.linkedToDeath) {
16815                        rl.linkedToDeath = false;
16816                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16817                    }
16818                }
16819            }
16820
16821            // If we actually concluded any broadcasts, we might now be able
16822            // to trim the recipients' apps from our working set
16823            if (doTrim) {
16824                trimApplications();
16825                return;
16826            }
16827
16828        } finally {
16829            Binder.restoreCallingIdentity(origId);
16830        }
16831    }
16832
16833    void removeReceiverLocked(ReceiverList rl) {
16834        mRegisteredReceivers.remove(rl.receiver.asBinder());
16835        for (int i = rl.size() - 1; i >= 0; i--) {
16836            mReceiverResolver.removeFilter(rl.get(i));
16837        }
16838    }
16839
16840    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16841        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16842            ProcessRecord r = mLruProcesses.get(i);
16843            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16844                try {
16845                    r.thread.dispatchPackageBroadcast(cmd, packages);
16846                } catch (RemoteException ex) {
16847                }
16848            }
16849        }
16850    }
16851
16852    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16853            int callingUid, int[] users) {
16854        // TODO: come back and remove this assumption to triage all broadcasts
16855        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16856
16857        List<ResolveInfo> receivers = null;
16858        try {
16859            HashSet<ComponentName> singleUserReceivers = null;
16860            boolean scannedFirstReceivers = false;
16861            for (int user : users) {
16862                // Skip users that have Shell restrictions, with exception of always permitted
16863                // Shell broadcasts
16864                if (callingUid == Process.SHELL_UID
16865                        && mUserController.hasUserRestriction(
16866                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16867                        && !isPermittedShellBroadcast(intent)) {
16868                    continue;
16869                }
16870                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16871                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
16872                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16873                    // If this is not the system user, we need to check for
16874                    // any receivers that should be filtered out.
16875                    for (int i=0; i<newReceivers.size(); i++) {
16876                        ResolveInfo ri = newReceivers.get(i);
16877                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16878                            newReceivers.remove(i);
16879                            i--;
16880                        }
16881                    }
16882                }
16883                if (newReceivers != null && newReceivers.size() == 0) {
16884                    newReceivers = null;
16885                }
16886                if (receivers == null) {
16887                    receivers = newReceivers;
16888                } else if (newReceivers != null) {
16889                    // We need to concatenate the additional receivers
16890                    // found with what we have do far.  This would be easy,
16891                    // but we also need to de-dup any receivers that are
16892                    // singleUser.
16893                    if (!scannedFirstReceivers) {
16894                        // Collect any single user receivers we had already retrieved.
16895                        scannedFirstReceivers = true;
16896                        for (int i=0; i<receivers.size(); i++) {
16897                            ResolveInfo ri = receivers.get(i);
16898                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16899                                ComponentName cn = new ComponentName(
16900                                        ri.activityInfo.packageName, ri.activityInfo.name);
16901                                if (singleUserReceivers == null) {
16902                                    singleUserReceivers = new HashSet<ComponentName>();
16903                                }
16904                                singleUserReceivers.add(cn);
16905                            }
16906                        }
16907                    }
16908                    // Add the new results to the existing results, tracking
16909                    // and de-dupping single user receivers.
16910                    for (int i=0; i<newReceivers.size(); i++) {
16911                        ResolveInfo ri = newReceivers.get(i);
16912                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16913                            ComponentName cn = new ComponentName(
16914                                    ri.activityInfo.packageName, ri.activityInfo.name);
16915                            if (singleUserReceivers == null) {
16916                                singleUserReceivers = new HashSet<ComponentName>();
16917                            }
16918                            if (!singleUserReceivers.contains(cn)) {
16919                                singleUserReceivers.add(cn);
16920                                receivers.add(ri);
16921                            }
16922                        } else {
16923                            receivers.add(ri);
16924                        }
16925                    }
16926                }
16927            }
16928        } catch (RemoteException ex) {
16929            // pm is in same process, this will never happen.
16930        }
16931        return receivers;
16932    }
16933
16934    private boolean isPermittedShellBroadcast(Intent intent) {
16935        // remote bugreport should always be allowed to be taken
16936        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
16937    }
16938
16939    final int broadcastIntentLocked(ProcessRecord callerApp,
16940            String callerPackage, Intent intent, String resolvedType,
16941            IIntentReceiver resultTo, int resultCode, String resultData,
16942            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16943            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16944        intent = new Intent(intent);
16945
16946        // By default broadcasts do not go to stopped apps.
16947        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16948
16949        // If we have not finished booting, don't allow this to launch new processes.
16950        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16951            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16952        }
16953
16954        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16955                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16956                + " ordered=" + ordered + " userid=" + userId);
16957        if ((resultTo != null) && !ordered) {
16958            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16959        }
16960
16961        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16962                ALLOW_NON_FULL, "broadcast", callerPackage);
16963
16964        // Make sure that the user who is receiving this broadcast is running.
16965        // If not, we will just skip it. Make an exception for shutdown broadcasts
16966        // and upgrade steps.
16967
16968        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16969            if ((callingUid != Process.SYSTEM_UID
16970                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16971                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16972                Slog.w(TAG, "Skipping broadcast of " + intent
16973                        + ": user " + userId + " is stopped");
16974                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16975            }
16976        }
16977
16978        BroadcastOptions brOptions = null;
16979        if (bOptions != null) {
16980            brOptions = new BroadcastOptions(bOptions);
16981            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16982                // See if the caller is allowed to do this.  Note we are checking against
16983                // the actual real caller (not whoever provided the operation as say a
16984                // PendingIntent), because that who is actually supplied the arguments.
16985                if (checkComponentPermission(
16986                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16987                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16988                        != PackageManager.PERMISSION_GRANTED) {
16989                    String msg = "Permission Denial: " + intent.getAction()
16990                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16991                            + ", uid=" + callingUid + ")"
16992                            + " requires "
16993                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16994                    Slog.w(TAG, msg);
16995                    throw new SecurityException(msg);
16996                }
16997            }
16998        }
16999
17000        // Verify that protected broadcasts are only being sent by system code,
17001        // and that system code is only sending protected broadcasts.
17002        final String action = intent.getAction();
17003        final boolean isProtectedBroadcast;
17004        try {
17005            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17006        } catch (RemoteException e) {
17007            Slog.w(TAG, "Remote exception", e);
17008            return ActivityManager.BROADCAST_SUCCESS;
17009        }
17010
17011        final boolean isCallerSystem;
17012        switch (UserHandle.getAppId(callingUid)) {
17013            case Process.ROOT_UID:
17014            case Process.SYSTEM_UID:
17015            case Process.PHONE_UID:
17016            case Process.BLUETOOTH_UID:
17017            case Process.NFC_UID:
17018                isCallerSystem = true;
17019                break;
17020            default:
17021                isCallerSystem = (callerApp != null) && callerApp.persistent;
17022                break;
17023        }
17024
17025        if (isCallerSystem) {
17026            if (isProtectedBroadcast
17027                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17028                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17029                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17030                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17031                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17032                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17033                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17034                // Broadcast is either protected, or it's a public action that
17035                // we've relaxed, so it's fine for system internals to send.
17036            } else {
17037                // The vast majority of broadcasts sent from system internals
17038                // should be protected to avoid security holes, so yell loudly
17039                // to ensure we examine these cases.
17040                Log.wtf(TAG, "Sending non-protected broadcast " + action
17041                        + " from system", new Throwable());
17042            }
17043
17044        } else {
17045            if (isProtectedBroadcast) {
17046                String msg = "Permission Denial: not allowed to send broadcast "
17047                        + action + " from pid="
17048                        + callingPid + ", uid=" + callingUid;
17049                Slog.w(TAG, msg);
17050                throw new SecurityException(msg);
17051
17052            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17053                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17054                // Special case for compatibility: we don't want apps to send this,
17055                // but historically it has not been protected and apps may be using it
17056                // to poke their own app widget.  So, instead of making it protected,
17057                // just limit it to the caller.
17058                if (callerApp == null) {
17059                    String msg = "Permission Denial: not allowed to send broadcast "
17060                            + action + " from unknown caller.";
17061                    Slog.w(TAG, msg);
17062                    throw new SecurityException(msg);
17063                } else if (intent.getComponent() != null) {
17064                    // They are good enough to send to an explicit component...  verify
17065                    // it is being sent to the calling app.
17066                    if (!intent.getComponent().getPackageName().equals(
17067                            callerApp.info.packageName)) {
17068                        String msg = "Permission Denial: not allowed to send broadcast "
17069                                + action + " to "
17070                                + intent.getComponent().getPackageName() + " from "
17071                                + callerApp.info.packageName;
17072                        Slog.w(TAG, msg);
17073                        throw new SecurityException(msg);
17074                    }
17075                } else {
17076                    // Limit broadcast to their own package.
17077                    intent.setPackage(callerApp.info.packageName);
17078                }
17079            }
17080        }
17081
17082        if (action != null) {
17083            switch (action) {
17084                case Intent.ACTION_UID_REMOVED:
17085                case Intent.ACTION_PACKAGE_REMOVED:
17086                case Intent.ACTION_PACKAGE_CHANGED:
17087                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17088                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17089                case Intent.ACTION_PACKAGES_SUSPENDED:
17090                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17091                    // Handle special intents: if this broadcast is from the package
17092                    // manager about a package being removed, we need to remove all of
17093                    // its activities from the history stack.
17094                    if (checkComponentPermission(
17095                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17096                            callingPid, callingUid, -1, true)
17097                            != PackageManager.PERMISSION_GRANTED) {
17098                        String msg = "Permission Denial: " + intent.getAction()
17099                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17100                                + ", uid=" + callingUid + ")"
17101                                + " requires "
17102                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17103                        Slog.w(TAG, msg);
17104                        throw new SecurityException(msg);
17105                    }
17106                    switch (action) {
17107                        case Intent.ACTION_UID_REMOVED:
17108                            final Bundle intentExtras = intent.getExtras();
17109                            final int uid = intentExtras != null
17110                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17111                            if (uid >= 0) {
17112                                mBatteryStatsService.removeUid(uid);
17113                                mAppOpsService.uidRemoved(uid);
17114                            }
17115                            break;
17116                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17117                            // If resources are unavailable just force stop all those packages
17118                            // and flush the attribute cache as well.
17119                            String list[] =
17120                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17121                            if (list != null && list.length > 0) {
17122                                for (int i = 0; i < list.length; i++) {
17123                                    forceStopPackageLocked(list[i], -1, false, true, true,
17124                                            false, false, userId, "storage unmount");
17125                                }
17126                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17127                                sendPackageBroadcastLocked(
17128                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17129                                        userId);
17130                            }
17131                            break;
17132                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17133                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17134                            break;
17135                        case Intent.ACTION_PACKAGE_REMOVED:
17136                        case Intent.ACTION_PACKAGE_CHANGED:
17137                            Uri data = intent.getData();
17138                            String ssp;
17139                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17140                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17141                                boolean fullUninstall = removed &&
17142                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17143                                final boolean killProcess =
17144                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17145                                if (killProcess) {
17146                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17147                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17148                                            false, true, true, false, fullUninstall, userId,
17149                                            removed ? "pkg removed" : "pkg changed");
17150                                }
17151                                if (removed) {
17152                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17153                                            new String[] {ssp}, userId);
17154                                    if (fullUninstall) {
17155                                        mAppOpsService.packageRemoved(
17156                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17157
17158                                        // Remove all permissions granted from/to this package
17159                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17160
17161                                        removeTasksByPackageNameLocked(ssp, userId);
17162                                        mBatteryStatsService.notePackageUninstalled(ssp);
17163                                    }
17164                                } else {
17165                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17166                                            intent.getStringArrayExtra(
17167                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17168                                }
17169                            }
17170                            break;
17171                        case Intent.ACTION_PACKAGES_SUSPENDED:
17172                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17173                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17174                                    intent.getAction());
17175                            final String[] packageNames = intent.getStringArrayExtra(
17176                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17177                            final int userHandle = intent.getIntExtra(
17178                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17179
17180                            synchronized(ActivityManagerService.this) {
17181                                mRecentTasks.onPackagesSuspendedChanged(
17182                                        packageNames, suspended, userHandle);
17183                            }
17184                            break;
17185                    }
17186                    break;
17187                case Intent.ACTION_PACKAGE_ADDED:
17188                    // Special case for adding a package: by default turn on compatibility mode.
17189                    Uri data = intent.getData();
17190                    String ssp;
17191                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17192                        final boolean replacing =
17193                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17194                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17195
17196                        try {
17197                            ApplicationInfo ai = AppGlobals.getPackageManager().
17198                                    getApplicationInfo(ssp, 0, 0);
17199                            mBatteryStatsService.notePackageInstalled(ssp,
17200                                    ai != null ? ai.versionCode : 0);
17201                        } catch (RemoteException e) {
17202                        }
17203                    }
17204                    break;
17205                case Intent.ACTION_TIMEZONE_CHANGED:
17206                    // If this is the time zone changed action, queue up a message that will reset
17207                    // the timezone of all currently running processes. This message will get
17208                    // queued up before the broadcast happens.
17209                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17210                    break;
17211                case Intent.ACTION_TIME_CHANGED:
17212                    // If the user set the time, let all running processes know.
17213                    final int is24Hour =
17214                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17215                                    : 0;
17216                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17217                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17218                    synchronized (stats) {
17219                        stats.noteCurrentTimeChangedLocked();
17220                    }
17221                    break;
17222                case Intent.ACTION_CLEAR_DNS_CACHE:
17223                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17224                    break;
17225                case Proxy.PROXY_CHANGE_ACTION:
17226                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17227                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17228                    break;
17229                case android.hardware.Camera.ACTION_NEW_PICTURE:
17230                case android.hardware.Camera.ACTION_NEW_VIDEO:
17231                    // These broadcasts are no longer allowed by the system, since they can
17232                    // cause significant thrashing at a crictical point (using the camera).
17233                    // Apps should use JobScehduler to monitor for media provider changes.
17234                    Slog.w(TAG, action + " no longer allowed; dropping from "
17235                            + UserHandle.formatUid(callingUid));
17236                    // Lie; we don't want to crash the app.
17237                    return ActivityManager.BROADCAST_SUCCESS;
17238            }
17239        }
17240
17241        // Add to the sticky list if requested.
17242        if (sticky) {
17243            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17244                    callingPid, callingUid)
17245                    != PackageManager.PERMISSION_GRANTED) {
17246                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17247                        + callingPid + ", uid=" + callingUid
17248                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17249                Slog.w(TAG, msg);
17250                throw new SecurityException(msg);
17251            }
17252            if (requiredPermissions != null && requiredPermissions.length > 0) {
17253                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17254                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17255                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17256            }
17257            if (intent.getComponent() != null) {
17258                throw new SecurityException(
17259                        "Sticky broadcasts can't target a specific component");
17260            }
17261            // We use userId directly here, since the "all" target is maintained
17262            // as a separate set of sticky broadcasts.
17263            if (userId != UserHandle.USER_ALL) {
17264                // But first, if this is not a broadcast to all users, then
17265                // make sure it doesn't conflict with an existing broadcast to
17266                // all users.
17267                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17268                        UserHandle.USER_ALL);
17269                if (stickies != null) {
17270                    ArrayList<Intent> list = stickies.get(intent.getAction());
17271                    if (list != null) {
17272                        int N = list.size();
17273                        int i;
17274                        for (i=0; i<N; i++) {
17275                            if (intent.filterEquals(list.get(i))) {
17276                                throw new IllegalArgumentException(
17277                                        "Sticky broadcast " + intent + " for user "
17278                                        + userId + " conflicts with existing global broadcast");
17279                            }
17280                        }
17281                    }
17282                }
17283            }
17284            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17285            if (stickies == null) {
17286                stickies = new ArrayMap<>();
17287                mStickyBroadcasts.put(userId, stickies);
17288            }
17289            ArrayList<Intent> list = stickies.get(intent.getAction());
17290            if (list == null) {
17291                list = new ArrayList<>();
17292                stickies.put(intent.getAction(), list);
17293            }
17294            final int stickiesCount = list.size();
17295            int i;
17296            for (i = 0; i < stickiesCount; i++) {
17297                if (intent.filterEquals(list.get(i))) {
17298                    // This sticky already exists, replace it.
17299                    list.set(i, new Intent(intent));
17300                    break;
17301                }
17302            }
17303            if (i >= stickiesCount) {
17304                list.add(new Intent(intent));
17305            }
17306        }
17307
17308        int[] users;
17309        if (userId == UserHandle.USER_ALL) {
17310            // Caller wants broadcast to go to all started users.
17311            users = mUserController.getStartedUserArrayLocked();
17312        } else {
17313            // Caller wants broadcast to go to one specific user.
17314            users = new int[] {userId};
17315        }
17316
17317        // Figure out who all will receive this broadcast.
17318        List receivers = null;
17319        List<BroadcastFilter> registeredReceivers = null;
17320        // Need to resolve the intent to interested receivers...
17321        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17322                 == 0) {
17323            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17324        }
17325        if (intent.getComponent() == null) {
17326            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17327                // Query one target user at a time, excluding shell-restricted users
17328                for (int i = 0; i < users.length; i++) {
17329                    if (mUserController.hasUserRestriction(
17330                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17331                        continue;
17332                    }
17333                    List<BroadcastFilter> registeredReceiversForUser =
17334                            mReceiverResolver.queryIntent(intent,
17335                                    resolvedType, false, users[i]);
17336                    if (registeredReceivers == null) {
17337                        registeredReceivers = registeredReceiversForUser;
17338                    } else if (registeredReceiversForUser != null) {
17339                        registeredReceivers.addAll(registeredReceiversForUser);
17340                    }
17341                }
17342            } else {
17343                registeredReceivers = mReceiverResolver.queryIntent(intent,
17344                        resolvedType, false, userId);
17345            }
17346        }
17347
17348        final boolean replacePending =
17349                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17350
17351        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17352                + " replacePending=" + replacePending);
17353
17354        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17355        if (!ordered && NR > 0) {
17356            // If we are not serializing this broadcast, then send the
17357            // registered receivers separately so they don't wait for the
17358            // components to be launched.
17359            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17360            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17361                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17362                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17363                    resultExtras, ordered, sticky, false, userId);
17364            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17365            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17366            if (!replaced) {
17367                queue.enqueueParallelBroadcastLocked(r);
17368                queue.scheduleBroadcastsLocked();
17369            }
17370            registeredReceivers = null;
17371            NR = 0;
17372        }
17373
17374        // Merge into one list.
17375        int ir = 0;
17376        if (receivers != null) {
17377            // A special case for PACKAGE_ADDED: do not allow the package
17378            // being added to see this broadcast.  This prevents them from
17379            // using this as a back door to get run as soon as they are
17380            // installed.  Maybe in the future we want to have a special install
17381            // broadcast or such for apps, but we'd like to deliberately make
17382            // this decision.
17383            String skipPackages[] = null;
17384            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17385                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17386                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17387                Uri data = intent.getData();
17388                if (data != null) {
17389                    String pkgName = data.getSchemeSpecificPart();
17390                    if (pkgName != null) {
17391                        skipPackages = new String[] { pkgName };
17392                    }
17393                }
17394            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17395                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17396            }
17397            if (skipPackages != null && (skipPackages.length > 0)) {
17398                for (String skipPackage : skipPackages) {
17399                    if (skipPackage != null) {
17400                        int NT = receivers.size();
17401                        for (int it=0; it<NT; it++) {
17402                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17403                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17404                                receivers.remove(it);
17405                                it--;
17406                                NT--;
17407                            }
17408                        }
17409                    }
17410                }
17411            }
17412
17413            int NT = receivers != null ? receivers.size() : 0;
17414            int it = 0;
17415            ResolveInfo curt = null;
17416            BroadcastFilter curr = null;
17417            while (it < NT && ir < NR) {
17418                if (curt == null) {
17419                    curt = (ResolveInfo)receivers.get(it);
17420                }
17421                if (curr == null) {
17422                    curr = registeredReceivers.get(ir);
17423                }
17424                if (curr.getPriority() >= curt.priority) {
17425                    // Insert this broadcast record into the final list.
17426                    receivers.add(it, curr);
17427                    ir++;
17428                    curr = null;
17429                    it++;
17430                    NT++;
17431                } else {
17432                    // Skip to the next ResolveInfo in the final list.
17433                    it++;
17434                    curt = null;
17435                }
17436            }
17437        }
17438        while (ir < NR) {
17439            if (receivers == null) {
17440                receivers = new ArrayList();
17441            }
17442            receivers.add(registeredReceivers.get(ir));
17443            ir++;
17444        }
17445
17446        if ((receivers != null && receivers.size() > 0)
17447                || resultTo != null) {
17448            BroadcastQueue queue = broadcastQueueForIntent(intent);
17449            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17450                    callerPackage, callingPid, callingUid, resolvedType,
17451                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17452                    resultData, resultExtras, ordered, sticky, false, userId);
17453
17454            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17455                    + ": prev had " + queue.mOrderedBroadcasts.size());
17456            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17457                    "Enqueueing broadcast " + r.intent.getAction());
17458
17459            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17460            if (!replaced) {
17461                queue.enqueueOrderedBroadcastLocked(r);
17462                queue.scheduleBroadcastsLocked();
17463            }
17464        }
17465
17466        return ActivityManager.BROADCAST_SUCCESS;
17467    }
17468
17469    final Intent verifyBroadcastLocked(Intent intent) {
17470        // Refuse possible leaked file descriptors
17471        if (intent != null && intent.hasFileDescriptors() == true) {
17472            throw new IllegalArgumentException("File descriptors passed in Intent");
17473        }
17474
17475        int flags = intent.getFlags();
17476
17477        if (!mProcessesReady) {
17478            // if the caller really truly claims to know what they're doing, go
17479            // ahead and allow the broadcast without launching any receivers
17480            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17481                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17482            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17483                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17484                        + " before boot completion");
17485                throw new IllegalStateException("Cannot broadcast before boot completed");
17486            }
17487        }
17488
17489        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17490            throw new IllegalArgumentException(
17491                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17492        }
17493
17494        return intent;
17495    }
17496
17497    public final int broadcastIntent(IApplicationThread caller,
17498            Intent intent, String resolvedType, IIntentReceiver resultTo,
17499            int resultCode, String resultData, Bundle resultExtras,
17500            String[] requiredPermissions, int appOp, Bundle bOptions,
17501            boolean serialized, boolean sticky, int userId) {
17502        enforceNotIsolatedCaller("broadcastIntent");
17503        synchronized(this) {
17504            intent = verifyBroadcastLocked(intent);
17505
17506            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17507            final int callingPid = Binder.getCallingPid();
17508            final int callingUid = Binder.getCallingUid();
17509            final long origId = Binder.clearCallingIdentity();
17510            int res = broadcastIntentLocked(callerApp,
17511                    callerApp != null ? callerApp.info.packageName : null,
17512                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17513                    requiredPermissions, appOp, null, serialized, sticky,
17514                    callingPid, callingUid, userId);
17515            Binder.restoreCallingIdentity(origId);
17516            return res;
17517        }
17518    }
17519
17520
17521    int broadcastIntentInPackage(String packageName, int uid,
17522            Intent intent, String resolvedType, IIntentReceiver resultTo,
17523            int resultCode, String resultData, Bundle resultExtras,
17524            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17525            int userId) {
17526        synchronized(this) {
17527            intent = verifyBroadcastLocked(intent);
17528
17529            final long origId = Binder.clearCallingIdentity();
17530            String[] requiredPermissions = requiredPermission == null ? null
17531                    : new String[] {requiredPermission};
17532            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17533                    resultTo, resultCode, resultData, resultExtras,
17534                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17535                    sticky, -1, uid, userId);
17536            Binder.restoreCallingIdentity(origId);
17537            return res;
17538        }
17539    }
17540
17541    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17542        // Refuse possible leaked file descriptors
17543        if (intent != null && intent.hasFileDescriptors() == true) {
17544            throw new IllegalArgumentException("File descriptors passed in Intent");
17545        }
17546
17547        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17548                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17549
17550        synchronized(this) {
17551            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17552                    != PackageManager.PERMISSION_GRANTED) {
17553                String msg = "Permission Denial: unbroadcastIntent() from pid="
17554                        + Binder.getCallingPid()
17555                        + ", uid=" + Binder.getCallingUid()
17556                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17557                Slog.w(TAG, msg);
17558                throw new SecurityException(msg);
17559            }
17560            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17561            if (stickies != null) {
17562                ArrayList<Intent> list = stickies.get(intent.getAction());
17563                if (list != null) {
17564                    int N = list.size();
17565                    int i;
17566                    for (i=0; i<N; i++) {
17567                        if (intent.filterEquals(list.get(i))) {
17568                            list.remove(i);
17569                            break;
17570                        }
17571                    }
17572                    if (list.size() <= 0) {
17573                        stickies.remove(intent.getAction());
17574                    }
17575                }
17576                if (stickies.size() <= 0) {
17577                    mStickyBroadcasts.remove(userId);
17578                }
17579            }
17580        }
17581    }
17582
17583    void backgroundServicesFinishedLocked(int userId) {
17584        for (BroadcastQueue queue : mBroadcastQueues) {
17585            queue.backgroundServicesFinishedLocked(userId);
17586        }
17587    }
17588
17589    public void finishReceiver(IBinder who, int resultCode, String resultData,
17590            Bundle resultExtras, boolean resultAbort, int flags) {
17591        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17592
17593        // Refuse possible leaked file descriptors
17594        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17595            throw new IllegalArgumentException("File descriptors passed in Bundle");
17596        }
17597
17598        final long origId = Binder.clearCallingIdentity();
17599        try {
17600            boolean doNext = false;
17601            BroadcastRecord r;
17602
17603            synchronized(this) {
17604                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17605                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17606                r = queue.getMatchingOrderedReceiver(who);
17607                if (r != null) {
17608                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17609                        resultData, resultExtras, resultAbort, true);
17610                }
17611            }
17612
17613            if (doNext) {
17614                r.queue.processNextBroadcast(false);
17615            }
17616            trimApplications();
17617        } finally {
17618            Binder.restoreCallingIdentity(origId);
17619        }
17620    }
17621
17622    // =========================================================
17623    // INSTRUMENTATION
17624    // =========================================================
17625
17626    public boolean startInstrumentation(ComponentName className,
17627            String profileFile, int flags, Bundle arguments,
17628            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17629            int userId, String abiOverride) {
17630        enforceNotIsolatedCaller("startInstrumentation");
17631        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17632                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17633        // Refuse possible leaked file descriptors
17634        if (arguments != null && arguments.hasFileDescriptors()) {
17635            throw new IllegalArgumentException("File descriptors passed in Bundle");
17636        }
17637
17638        synchronized(this) {
17639            InstrumentationInfo ii = null;
17640            ApplicationInfo ai = null;
17641            try {
17642                ii = mContext.getPackageManager().getInstrumentationInfo(
17643                    className, STOCK_PM_FLAGS);
17644                ai = AppGlobals.getPackageManager().getApplicationInfo(
17645                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17646            } catch (PackageManager.NameNotFoundException e) {
17647            } catch (RemoteException e) {
17648            }
17649            if (ii == null) {
17650                reportStartInstrumentationFailure(watcher, className,
17651                        "Unable to find instrumentation info for: " + className);
17652                return false;
17653            }
17654            if (ai == null) {
17655                reportStartInstrumentationFailure(watcher, className,
17656                        "Unable to find instrumentation target package: " + ii.targetPackage);
17657                return false;
17658            }
17659            if (!ai.hasCode()) {
17660                reportStartInstrumentationFailure(watcher, className,
17661                        "Instrumentation target has no code: " + ii.targetPackage);
17662                return false;
17663            }
17664
17665            int match = mContext.getPackageManager().checkSignatures(
17666                    ii.targetPackage, ii.packageName);
17667            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17668                String msg = "Permission Denial: starting instrumentation "
17669                        + className + " from pid="
17670                        + Binder.getCallingPid()
17671                        + ", uid=" + Binder.getCallingPid()
17672                        + " not allowed because package " + ii.packageName
17673                        + " does not have a signature matching the target "
17674                        + ii.targetPackage;
17675                reportStartInstrumentationFailure(watcher, className, msg);
17676                throw new SecurityException(msg);
17677            }
17678
17679            final long origId = Binder.clearCallingIdentity();
17680            // Instrumentation can kill and relaunch even persistent processes
17681            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17682                    "start instr");
17683            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17684            app.instrumentationClass = className;
17685            app.instrumentationInfo = ai;
17686            app.instrumentationProfileFile = profileFile;
17687            app.instrumentationArguments = arguments;
17688            app.instrumentationWatcher = watcher;
17689            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17690            app.instrumentationResultClass = className;
17691            Binder.restoreCallingIdentity(origId);
17692        }
17693
17694        return true;
17695    }
17696
17697    /**
17698     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17699     * error to the logs, but if somebody is watching, send the report there too.  This enables
17700     * the "am" command to report errors with more information.
17701     *
17702     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17703     * @param cn The component name of the instrumentation.
17704     * @param report The error report.
17705     */
17706    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17707            ComponentName cn, String report) {
17708        Slog.w(TAG, report);
17709        try {
17710            if (watcher != null) {
17711                Bundle results = new Bundle();
17712                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17713                results.putString("Error", report);
17714                watcher.instrumentationStatus(cn, -1, results);
17715            }
17716        } catch (RemoteException e) {
17717            Slog.w(TAG, e);
17718        }
17719    }
17720
17721    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17722        if (app.instrumentationWatcher != null) {
17723            try {
17724                // NOTE:  IInstrumentationWatcher *must* be oneway here
17725                app.instrumentationWatcher.instrumentationFinished(
17726                    app.instrumentationClass,
17727                    resultCode,
17728                    results);
17729            } catch (RemoteException e) {
17730            }
17731        }
17732
17733        // Can't call out of the system process with a lock held, so post a message.
17734        if (app.instrumentationUiAutomationConnection != null) {
17735            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17736                    app.instrumentationUiAutomationConnection).sendToTarget();
17737        }
17738
17739        app.instrumentationWatcher = null;
17740        app.instrumentationUiAutomationConnection = null;
17741        app.instrumentationClass = null;
17742        app.instrumentationInfo = null;
17743        app.instrumentationProfileFile = null;
17744        app.instrumentationArguments = null;
17745
17746        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17747                "finished inst");
17748    }
17749
17750    public void finishInstrumentation(IApplicationThread target,
17751            int resultCode, Bundle results) {
17752        int userId = UserHandle.getCallingUserId();
17753        // Refuse possible leaked file descriptors
17754        if (results != null && results.hasFileDescriptors()) {
17755            throw new IllegalArgumentException("File descriptors passed in Intent");
17756        }
17757
17758        synchronized(this) {
17759            ProcessRecord app = getRecordForAppLocked(target);
17760            if (app == null) {
17761                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17762                return;
17763            }
17764            final long origId = Binder.clearCallingIdentity();
17765            finishInstrumentationLocked(app, resultCode, results);
17766            Binder.restoreCallingIdentity(origId);
17767        }
17768    }
17769
17770    // =========================================================
17771    // CONFIGURATION
17772    // =========================================================
17773
17774    public ConfigurationInfo getDeviceConfigurationInfo() {
17775        ConfigurationInfo config = new ConfigurationInfo();
17776        synchronized (this) {
17777            config.reqTouchScreen = mConfiguration.touchscreen;
17778            config.reqKeyboardType = mConfiguration.keyboard;
17779            config.reqNavigation = mConfiguration.navigation;
17780            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17781                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17782                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17783            }
17784            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17785                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17786                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17787            }
17788            config.reqGlEsVersion = GL_ES_VERSION;
17789        }
17790        return config;
17791    }
17792
17793    ActivityStack getFocusedStack() {
17794        return mStackSupervisor.getFocusedStack();
17795    }
17796
17797    @Override
17798    public int getFocusedStackId() throws RemoteException {
17799        ActivityStack focusedStack = getFocusedStack();
17800        if (focusedStack != null) {
17801            return focusedStack.getStackId();
17802        }
17803        return -1;
17804    }
17805
17806    public Configuration getConfiguration() {
17807        Configuration ci;
17808        synchronized(this) {
17809            ci = new Configuration(mConfiguration);
17810            ci.userSetLocale = false;
17811        }
17812        return ci;
17813    }
17814
17815    @Override
17816    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17817        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17818        synchronized (this) {
17819            mSuppressResizeConfigChanges = suppress;
17820        }
17821    }
17822
17823    @Override
17824    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17825        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17826        if (fromStackId == HOME_STACK_ID) {
17827            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17828        }
17829        synchronized (this) {
17830            final long origId = Binder.clearCallingIdentity();
17831            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17832            if (stack != null) {
17833                mWindowManager.deferSurfaceLayout();
17834                try {
17835                    if (fromStackId == DOCKED_STACK_ID) {
17836
17837                        // We are moving all tasks from the docked stack to the fullscreen stack,
17838                        // which is dismissing the docked stack, so resize all other stacks to
17839                        // fullscreen here already so we don't end up with resize trashing.
17840                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17841                            if (StackId.isResizeableByDockedStack(i)) {
17842                                ActivityStack otherStack = mStackSupervisor.getStack(i);
17843                                if (otherStack != null) {
17844                                    mStackSupervisor.resizeStackLocked(i,
17845                                            null, null, null, PRESERVE_WINDOWS,
17846                                            true /* allowResizeInDockedMode */);
17847                                }
17848                            }
17849                        }
17850                    }
17851                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17852                    final int size = tasks.size();
17853                    if (onTop) {
17854                        for (int i = 0; i < size; i++) {
17855                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17856                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
17857                                    "moveTasksToFullscreenStack", ANIMATE);
17858                        }
17859                    } else {
17860                        for (int i = size - 1; i >= 0; i--) {
17861                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17862                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
17863                        }
17864                    }
17865                } finally {
17866                    mWindowManager.continueSurfaceLayout();
17867                }
17868
17869            }
17870            Binder.restoreCallingIdentity(origId);
17871        }
17872    }
17873
17874    @Override
17875    public void updatePersistentConfiguration(Configuration values) {
17876        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17877                "updateConfiguration()");
17878        enforceWriteSettingsPermission("updateConfiguration()");
17879        if (values == null) {
17880            throw new NullPointerException("Configuration must not be null");
17881        }
17882
17883        int userId = UserHandle.getCallingUserId();
17884
17885        synchronized(this) {
17886            final long origId = Binder.clearCallingIdentity();
17887            updateConfigurationLocked(values, null, false, true, userId);
17888            Binder.restoreCallingIdentity(origId);
17889        }
17890    }
17891
17892    private void updateFontScaleIfNeeded() {
17893        final int currentUserId;
17894        synchronized(this) {
17895            currentUserId = mUserController.getCurrentUserIdLocked();
17896        }
17897        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17898                FONT_SCALE, 1.0f, currentUserId);
17899        if (mConfiguration.fontScale != scaleFactor) {
17900            final Configuration configuration = mWindowManager.computeNewConfiguration();
17901            configuration.fontScale = scaleFactor;
17902            updatePersistentConfiguration(configuration);
17903        }
17904    }
17905
17906    private void enforceWriteSettingsPermission(String func) {
17907        int uid = Binder.getCallingUid();
17908        if (uid == Process.ROOT_UID) {
17909            return;
17910        }
17911
17912        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17913                Settings.getPackageNameForUid(mContext, uid), false)) {
17914            return;
17915        }
17916
17917        String msg = "Permission Denial: " + func + " from pid="
17918                + Binder.getCallingPid()
17919                + ", uid=" + uid
17920                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17921        Slog.w(TAG, msg);
17922        throw new SecurityException(msg);
17923    }
17924
17925    public void updateConfiguration(Configuration values) {
17926        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17927                "updateConfiguration()");
17928
17929        synchronized(this) {
17930            if (values == null && mWindowManager != null) {
17931                // sentinel: fetch the current configuration from the window manager
17932                values = mWindowManager.computeNewConfiguration();
17933            }
17934
17935            if (mWindowManager != null) {
17936                mProcessList.applyDisplaySize(mWindowManager);
17937            }
17938
17939            final long origId = Binder.clearCallingIdentity();
17940            if (values != null) {
17941                Settings.System.clearConfiguration(values);
17942            }
17943            updateConfigurationLocked(values, null, false);
17944            Binder.restoreCallingIdentity(origId);
17945        }
17946    }
17947
17948    void updateUserConfigurationLocked() {
17949        Configuration configuration = new Configuration(mConfiguration);
17950        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17951                mUserController.getCurrentUserIdLocked());
17952        updateConfigurationLocked(configuration, null, false);
17953    }
17954
17955    boolean updateConfigurationLocked(Configuration values,
17956            ActivityRecord starting, boolean initLocale) {
17957        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17958        return updateConfigurationLocked(values, starting, initLocale, false,
17959                UserHandle.USER_NULL);
17960    }
17961
17962    // To cache the list of supported system locales
17963    private String[] mSupportedSystemLocales = null;
17964
17965    /**
17966     * Do either or both things: (1) change the current configuration, and (2)
17967     * make sure the given activity is running with the (now) current
17968     * configuration.  Returns true if the activity has been left running, or
17969     * false if <var>starting</var> is being destroyed to match the new
17970     * configuration.
17971     *
17972     * @param userId is only used when persistent parameter is set to true to persist configuration
17973     *               for that particular user
17974     */
17975    private boolean updateConfigurationLocked(Configuration values,
17976            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17977        int changes = 0;
17978
17979        if (values != null) {
17980            Configuration newConfig = new Configuration(mConfiguration);
17981            changes = newConfig.updateFrom(values);
17982            if (changes != 0) {
17983                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17984                        "Updating configuration to: " + values);
17985
17986                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17987
17988                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17989                    final Locale locale;
17990                    if (values.getLocales().size() == 1) {
17991                        // This is an optimization to avoid the JNI call when the result of
17992                        // getFirstMatch() does not depend on the supported locales.
17993                        locale = values.getLocales().get(0);
17994                    } else {
17995                        if (mSupportedSystemLocales == null) {
17996                            mSupportedSystemLocales =
17997                                    Resources.getSystem().getAssets().getLocales();
17998                        }
17999                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18000                    }
18001                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18002                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18003                            locale));
18004                }
18005
18006                mConfigurationSeq++;
18007                if (mConfigurationSeq <= 0) {
18008                    mConfigurationSeq = 1;
18009                }
18010                newConfig.seq = mConfigurationSeq;
18011                mConfiguration = newConfig;
18012                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18013                mUsageStatsService.reportConfigurationChange(newConfig,
18014                        mUserController.getCurrentUserIdLocked());
18015                //mUsageStatsService.noteStartConfig(newConfig);
18016
18017                final Configuration configCopy = new Configuration(mConfiguration);
18018
18019                // TODO: If our config changes, should we auto dismiss any currently
18020                // showing dialogs?
18021                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18022
18023                AttributeCache ac = AttributeCache.instance();
18024                if (ac != null) {
18025                    ac.updateConfiguration(configCopy);
18026                }
18027
18028                // Make sure all resources in our process are updated
18029                // right now, so that anyone who is going to retrieve
18030                // resource values after we return will be sure to get
18031                // the new ones.  This is especially important during
18032                // boot, where the first config change needs to guarantee
18033                // all resources have that config before following boot
18034                // code is executed.
18035                mSystemThread.applyConfigurationToResources(configCopy);
18036
18037                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18038                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18039                    msg.obj = new Configuration(configCopy);
18040                    msg.arg1 = userId;
18041                    mHandler.sendMessage(msg);
18042                }
18043
18044                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18045                if (isDensityChange) {
18046                    killAllBackgroundProcesses(Build.VERSION_CODES.N);
18047                }
18048
18049                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18050                    ProcessRecord app = mLruProcesses.get(i);
18051                    try {
18052                        if (app.thread != null) {
18053                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18054                                    + app.processName + " new config " + mConfiguration);
18055                            app.thread.scheduleConfigurationChanged(configCopy);
18056                        }
18057                    } catch (Exception e) {
18058                    }
18059                }
18060                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18061                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18062                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18063                        | Intent.FLAG_RECEIVER_FOREGROUND);
18064                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18065                        null, AppOpsManager.OP_NONE, null, false, false,
18066                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18067                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18068                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18069                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18070                    if (!mProcessesReady) {
18071                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18072                    }
18073                    broadcastIntentLocked(null, null, intent,
18074                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18075                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18076                }
18077            }
18078        }
18079
18080        boolean kept = true;
18081        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18082        // mainStack is null during startup.
18083        if (mainStack != null) {
18084            if (changes != 0 && starting == null) {
18085                // If the configuration changed, and the caller is not already
18086                // in the process of starting an activity, then find the top
18087                // activity to check if its configuration needs to change.
18088                starting = mainStack.topRunningActivityLocked();
18089            }
18090
18091            if (starting != null) {
18092                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18093                // And we need to make sure at this point that all other activities
18094                // are made visible with the correct configuration.
18095                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18096                        !PRESERVE_WINDOWS);
18097            }
18098        }
18099
18100        if (values != null && mWindowManager != null) {
18101            mWindowManager.setNewConfiguration(mConfiguration);
18102        }
18103
18104        return kept;
18105    }
18106
18107    /**
18108     * Decide based on the configuration whether we should shouw the ANR,
18109     * crash, etc dialogs.  The idea is that if there is no affordnace to
18110     * press the on-screen buttons, we shouldn't show the dialog.
18111     *
18112     * A thought: SystemUI might also want to get told about this, the Power
18113     * dialog / global actions also might want different behaviors.
18114     */
18115    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18116        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18117                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18118                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18119        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18120                                    == Configuration.UI_MODE_TYPE_CAR);
18121        return inputMethodExists && uiIsNotCarType && !inVrMode;
18122    }
18123
18124    @Override
18125    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18126        synchronized (this) {
18127            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18128            if (srec != null) {
18129                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18130            }
18131        }
18132        return false;
18133    }
18134
18135    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18136            Intent resultData) {
18137
18138        synchronized (this) {
18139            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18140            if (r != null) {
18141                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18142            }
18143            return false;
18144        }
18145    }
18146
18147    public int getLaunchedFromUid(IBinder activityToken) {
18148        ActivityRecord srec;
18149        synchronized (this) {
18150            srec = ActivityRecord.forTokenLocked(activityToken);
18151        }
18152        if (srec == null) {
18153            return -1;
18154        }
18155        return srec.launchedFromUid;
18156    }
18157
18158    public String getLaunchedFromPackage(IBinder activityToken) {
18159        ActivityRecord srec;
18160        synchronized (this) {
18161            srec = ActivityRecord.forTokenLocked(activityToken);
18162        }
18163        if (srec == null) {
18164            return null;
18165        }
18166        return srec.launchedFromPackage;
18167    }
18168
18169    // =========================================================
18170    // LIFETIME MANAGEMENT
18171    // =========================================================
18172
18173    // Returns which broadcast queue the app is the current [or imminent] receiver
18174    // on, or 'null' if the app is not an active broadcast recipient.
18175    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18176        BroadcastRecord r = app.curReceiver;
18177        if (r != null) {
18178            return r.queue;
18179        }
18180
18181        // It's not the current receiver, but it might be starting up to become one
18182        synchronized (this) {
18183            for (BroadcastQueue queue : mBroadcastQueues) {
18184                r = queue.mPendingBroadcast;
18185                if (r != null && r.curApp == app) {
18186                    // found it; report which queue it's in
18187                    return queue;
18188                }
18189            }
18190        }
18191
18192        return null;
18193    }
18194
18195    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18196            ComponentName targetComponent, String targetProcess) {
18197        if (!mTrackingAssociations) {
18198            return null;
18199        }
18200        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18201                = mAssociations.get(targetUid);
18202        if (components == null) {
18203            components = new ArrayMap<>();
18204            mAssociations.put(targetUid, components);
18205        }
18206        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18207        if (sourceUids == null) {
18208            sourceUids = new SparseArray<>();
18209            components.put(targetComponent, sourceUids);
18210        }
18211        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18212        if (sourceProcesses == null) {
18213            sourceProcesses = new ArrayMap<>();
18214            sourceUids.put(sourceUid, sourceProcesses);
18215        }
18216        Association ass = sourceProcesses.get(sourceProcess);
18217        if (ass == null) {
18218            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18219                    targetProcess);
18220            sourceProcesses.put(sourceProcess, ass);
18221        }
18222        ass.mCount++;
18223        ass.mNesting++;
18224        if (ass.mNesting == 1) {
18225            ass.mStartTime = SystemClock.uptimeMillis();
18226        }
18227        return ass;
18228    }
18229
18230    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18231            ComponentName targetComponent) {
18232        if (!mTrackingAssociations) {
18233            return;
18234        }
18235        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18236                = mAssociations.get(targetUid);
18237        if (components == null) {
18238            return;
18239        }
18240        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18241        if (sourceUids == null) {
18242            return;
18243        }
18244        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18245        if (sourceProcesses == null) {
18246            return;
18247        }
18248        Association ass = sourceProcesses.get(sourceProcess);
18249        if (ass == null || ass.mNesting <= 0) {
18250            return;
18251        }
18252        ass.mNesting--;
18253        if (ass.mNesting == 0) {
18254            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18255        }
18256    }
18257
18258    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18259            boolean doingAll, long now) {
18260        if (mAdjSeq == app.adjSeq) {
18261            // This adjustment has already been computed.
18262            return app.curRawAdj;
18263        }
18264
18265        if (app.thread == null) {
18266            app.adjSeq = mAdjSeq;
18267            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18268            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18269            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18270        }
18271
18272        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18273        app.adjSource = null;
18274        app.adjTarget = null;
18275        app.empty = false;
18276        app.cached = false;
18277
18278        final int activitiesSize = app.activities.size();
18279
18280        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18281            // The max adjustment doesn't allow this app to be anything
18282            // below foreground, so it is not worth doing work for it.
18283            app.adjType = "fixed";
18284            app.adjSeq = mAdjSeq;
18285            app.curRawAdj = app.maxAdj;
18286            app.foregroundActivities = false;
18287            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18288            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18289            // System processes can do UI, and when they do we want to have
18290            // them trim their memory after the user leaves the UI.  To
18291            // facilitate this, here we need to determine whether or not it
18292            // is currently showing UI.
18293            app.systemNoUi = true;
18294            if (app == TOP_APP) {
18295                app.systemNoUi = false;
18296            } else if (activitiesSize > 0) {
18297                for (int j = 0; j < activitiesSize; j++) {
18298                    final ActivityRecord r = app.activities.get(j);
18299                    if (r.visible) {
18300                        app.systemNoUi = false;
18301                    }
18302                }
18303            }
18304            if (!app.systemNoUi) {
18305                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18306            }
18307            return (app.curAdj=app.maxAdj);
18308        }
18309
18310        app.systemNoUi = false;
18311
18312        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18313
18314        // Determine the importance of the process, starting with most
18315        // important to least, and assign an appropriate OOM adjustment.
18316        int adj;
18317        int schedGroup;
18318        int procState;
18319        boolean foregroundActivities = false;
18320        BroadcastQueue queue;
18321        if (app == TOP_APP) {
18322            // The last app on the list is the foreground app.
18323            adj = ProcessList.FOREGROUND_APP_ADJ;
18324            schedGroup = Process.THREAD_GROUP_TOP_APP;
18325            app.adjType = "top-activity";
18326            foregroundActivities = true;
18327            procState = PROCESS_STATE_CUR_TOP;
18328        } else if (app.instrumentationClass != null) {
18329            // Don't want to kill running instrumentation.
18330            adj = ProcessList.FOREGROUND_APP_ADJ;
18331            schedGroup = Process.THREAD_GROUP_DEFAULT;
18332            app.adjType = "instrumentation";
18333            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18334        } else if ((queue = isReceivingBroadcast(app)) != null) {
18335            // An app that is currently receiving a broadcast also
18336            // counts as being in the foreground for OOM killer purposes.
18337            // It's placed in a sched group based on the nature of the
18338            // broadcast as reflected by which queue it's active in.
18339            adj = ProcessList.FOREGROUND_APP_ADJ;
18340            schedGroup = (queue == mFgBroadcastQueue)
18341                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18342            app.adjType = "broadcast";
18343            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18344        } else if (app.executingServices.size() > 0) {
18345            // An app that is currently executing a service callback also
18346            // counts as being in the foreground.
18347            adj = ProcessList.FOREGROUND_APP_ADJ;
18348            schedGroup = app.execServicesFg ?
18349                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18350            app.adjType = "exec-service";
18351            procState = ActivityManager.PROCESS_STATE_SERVICE;
18352            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18353        } else {
18354            // As far as we know the process is empty.  We may change our mind later.
18355            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18356            // At this point we don't actually know the adjustment.  Use the cached adj
18357            // value that the caller wants us to.
18358            adj = cachedAdj;
18359            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18360            app.cached = true;
18361            app.empty = true;
18362            app.adjType = "cch-empty";
18363        }
18364
18365        // Examine all activities if not already foreground.
18366        if (!foregroundActivities && activitiesSize > 0) {
18367            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18368            for (int j = 0; j < activitiesSize; j++) {
18369                final ActivityRecord r = app.activities.get(j);
18370                if (r.app != app) {
18371                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18372                            + app + "?!? Using " + r.app + " instead.");
18373                    continue;
18374                }
18375                if (r.visible) {
18376                    // App has a visible activity; only upgrade adjustment.
18377                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18378                        adj = ProcessList.VISIBLE_APP_ADJ;
18379                        app.adjType = "visible";
18380                    }
18381                    if (procState > PROCESS_STATE_CUR_TOP) {
18382                        procState = PROCESS_STATE_CUR_TOP;
18383                    }
18384                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18385                    app.cached = false;
18386                    app.empty = false;
18387                    foregroundActivities = true;
18388                    if (r.task != null && minLayer > 0) {
18389                        final int layer = r.task.mLayerRank;
18390                        if (layer >= 0 && minLayer > layer) {
18391                            minLayer = layer;
18392                        }
18393                    }
18394                    break;
18395                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18396                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18397                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18398                        app.adjType = "pausing";
18399                    }
18400                    if (procState > PROCESS_STATE_CUR_TOP) {
18401                        procState = PROCESS_STATE_CUR_TOP;
18402                    }
18403                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18404                    app.cached = false;
18405                    app.empty = false;
18406                    foregroundActivities = true;
18407                } else if (r.state == ActivityState.STOPPING) {
18408                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18409                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18410                        app.adjType = "stopping";
18411                    }
18412                    // For the process state, we will at this point consider the
18413                    // process to be cached.  It will be cached either as an activity
18414                    // or empty depending on whether the activity is finishing.  We do
18415                    // this so that we can treat the process as cached for purposes of
18416                    // memory trimming (determing current memory level, trim command to
18417                    // send to process) since there can be an arbitrary number of stopping
18418                    // processes and they should soon all go into the cached state.
18419                    if (!r.finishing) {
18420                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18421                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18422                        }
18423                    }
18424                    app.cached = false;
18425                    app.empty = false;
18426                    foregroundActivities = true;
18427                } else {
18428                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18429                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18430                        app.adjType = "cch-act";
18431                    }
18432                }
18433            }
18434            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18435                adj += minLayer;
18436            }
18437        }
18438
18439        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18440                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18441            if (app.foregroundServices) {
18442                // The user is aware of this app, so make it visible.
18443                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18444                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18445                app.cached = false;
18446                app.adjType = "fg-service";
18447                schedGroup = Process.THREAD_GROUP_DEFAULT;
18448            } else if (app.forcingToForeground != null) {
18449                // The user is aware of this app, so make it visible.
18450                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18451                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18452                app.cached = false;
18453                app.adjType = "force-fg";
18454                app.adjSource = app.forcingToForeground;
18455                schedGroup = Process.THREAD_GROUP_DEFAULT;
18456            }
18457        }
18458
18459        if (app == mHeavyWeightProcess) {
18460            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18461                // We don't want to kill the current heavy-weight process.
18462                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18463                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18464                app.cached = false;
18465                app.adjType = "heavy";
18466            }
18467            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18468                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18469            }
18470        }
18471
18472        if (app == mHomeProcess) {
18473            if (adj > ProcessList.HOME_APP_ADJ) {
18474                // This process is hosting what we currently consider to be the
18475                // home app, so we don't want to let it go into the background.
18476                adj = ProcessList.HOME_APP_ADJ;
18477                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18478                app.cached = false;
18479                app.adjType = "home";
18480            }
18481            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18482                procState = ActivityManager.PROCESS_STATE_HOME;
18483            }
18484        }
18485
18486        if (app == mPreviousProcess && app.activities.size() > 0) {
18487            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18488                // This was the previous process that showed UI to the user.
18489                // We want to try to keep it around more aggressively, to give
18490                // a good experience around switching between two apps.
18491                adj = ProcessList.PREVIOUS_APP_ADJ;
18492                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18493                app.cached = false;
18494                app.adjType = "previous";
18495            }
18496            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18497                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18498            }
18499        }
18500
18501        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18502                + " reason=" + app.adjType);
18503
18504        // By default, we use the computed adjustment.  It may be changed if
18505        // there are applications dependent on our services or providers, but
18506        // this gives us a baseline and makes sure we don't get into an
18507        // infinite recursion.
18508        app.adjSeq = mAdjSeq;
18509        app.curRawAdj = adj;
18510        app.hasStartedServices = false;
18511
18512        if (mBackupTarget != null && app == mBackupTarget.app) {
18513            // If possible we want to avoid killing apps while they're being backed up
18514            if (adj > ProcessList.BACKUP_APP_ADJ) {
18515                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18516                adj = ProcessList.BACKUP_APP_ADJ;
18517                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18518                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18519                }
18520                app.adjType = "backup";
18521                app.cached = false;
18522            }
18523            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18524                procState = ActivityManager.PROCESS_STATE_BACKUP;
18525            }
18526        }
18527
18528        boolean mayBeTop = false;
18529
18530        for (int is = app.services.size()-1;
18531                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18532                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18533                        || procState > ActivityManager.PROCESS_STATE_TOP);
18534                is--) {
18535            ServiceRecord s = app.services.valueAt(is);
18536            if (s.startRequested) {
18537                app.hasStartedServices = true;
18538                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18539                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18540                }
18541                if (app.hasShownUi && app != mHomeProcess) {
18542                    // If this process has shown some UI, let it immediately
18543                    // go to the LRU list because it may be pretty heavy with
18544                    // UI stuff.  We'll tag it with a label just to help
18545                    // debug and understand what is going on.
18546                    if (adj > ProcessList.SERVICE_ADJ) {
18547                        app.adjType = "cch-started-ui-services";
18548                    }
18549                } else {
18550                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18551                        // This service has seen some activity within
18552                        // recent memory, so we will keep its process ahead
18553                        // of the background processes.
18554                        if (adj > ProcessList.SERVICE_ADJ) {
18555                            adj = ProcessList.SERVICE_ADJ;
18556                            app.adjType = "started-services";
18557                            app.cached = false;
18558                        }
18559                    }
18560                    // If we have let the service slide into the background
18561                    // state, still have some text describing what it is doing
18562                    // even though the service no longer has an impact.
18563                    if (adj > ProcessList.SERVICE_ADJ) {
18564                        app.adjType = "cch-started-services";
18565                    }
18566                }
18567            }
18568            for (int conni = s.connections.size()-1;
18569                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18570                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18571                            || procState > ActivityManager.PROCESS_STATE_TOP);
18572                    conni--) {
18573                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18574                for (int i = 0;
18575                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18576                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18577                                || procState > ActivityManager.PROCESS_STATE_TOP);
18578                        i++) {
18579                    // XXX should compute this based on the max of
18580                    // all connected clients.
18581                    ConnectionRecord cr = clist.get(i);
18582                    if (cr.binding.client == app) {
18583                        // Binding to ourself is not interesting.
18584                        continue;
18585                    }
18586                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18587                        ProcessRecord client = cr.binding.client;
18588                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18589                                TOP_APP, doingAll, now);
18590                        int clientProcState = client.curProcState;
18591                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18592                            // If the other app is cached for any reason, for purposes here
18593                            // we are going to consider it empty.  The specific cached state
18594                            // doesn't propagate except under certain conditions.
18595                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18596                        }
18597                        String adjType = null;
18598                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18599                            // Not doing bind OOM management, so treat
18600                            // this guy more like a started service.
18601                            if (app.hasShownUi && app != mHomeProcess) {
18602                                // If this process has shown some UI, let it immediately
18603                                // go to the LRU list because it may be pretty heavy with
18604                                // UI stuff.  We'll tag it with a label just to help
18605                                // debug and understand what is going on.
18606                                if (adj > clientAdj) {
18607                                    adjType = "cch-bound-ui-services";
18608                                }
18609                                app.cached = false;
18610                                clientAdj = adj;
18611                                clientProcState = procState;
18612                            } else {
18613                                if (now >= (s.lastActivity
18614                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18615                                    // This service has not seen activity within
18616                                    // recent memory, so allow it to drop to the
18617                                    // LRU list if there is no other reason to keep
18618                                    // it around.  We'll also tag it with a label just
18619                                    // to help debug and undertand what is going on.
18620                                    if (adj > clientAdj) {
18621                                        adjType = "cch-bound-services";
18622                                    }
18623                                    clientAdj = adj;
18624                                }
18625                            }
18626                        }
18627                        if (adj > clientAdj) {
18628                            // If this process has recently shown UI, and
18629                            // the process that is binding to it is less
18630                            // important than being visible, then we don't
18631                            // care about the binding as much as we care
18632                            // about letting this process get into the LRU
18633                            // list to be killed and restarted if needed for
18634                            // memory.
18635                            if (app.hasShownUi && app != mHomeProcess
18636                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18637                                adjType = "cch-bound-ui-services";
18638                            } else {
18639                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18640                                        |Context.BIND_IMPORTANT)) != 0) {
18641                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18642                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18643                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18644                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18645                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18646                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18647                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18648                                    adj = clientAdj;
18649                                } else {
18650                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18651                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18652                                    }
18653                                }
18654                                if (!client.cached) {
18655                                    app.cached = false;
18656                                }
18657                                adjType = "service";
18658                            }
18659                        }
18660                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18661                            // This will treat important bound services identically to
18662                            // the top app, which may behave differently than generic
18663                            // foreground work.
18664                            if (client.curSchedGroup > schedGroup) {
18665                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18666                                    schedGroup = client.curSchedGroup;
18667                                } else {
18668                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18669                                }
18670                            }
18671                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18672                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18673                                    // Special handling of clients who are in the top state.
18674                                    // We *may* want to consider this process to be in the
18675                                    // top state as well, but only if there is not another
18676                                    // reason for it to be running.  Being on the top is a
18677                                    // special state, meaning you are specifically running
18678                                    // for the current top app.  If the process is already
18679                                    // running in the background for some other reason, it
18680                                    // is more important to continue considering it to be
18681                                    // in the background state.
18682                                    mayBeTop = true;
18683                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18684                                } else {
18685                                    // Special handling for above-top states (persistent
18686                                    // processes).  These should not bring the current process
18687                                    // into the top state, since they are not on top.  Instead
18688                                    // give them the best state after that.
18689                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18690                                        clientProcState =
18691                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18692                                    } else if (mWakefulness
18693                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18694                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18695                                                    != 0) {
18696                                        clientProcState =
18697                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18698                                    } else {
18699                                        clientProcState =
18700                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18701                                    }
18702                                }
18703                            }
18704                        } else {
18705                            if (clientProcState <
18706                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18707                                clientProcState =
18708                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18709                            }
18710                        }
18711                        if (procState > clientProcState) {
18712                            procState = clientProcState;
18713                        }
18714                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18715                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18716                            app.pendingUiClean = true;
18717                        }
18718                        if (adjType != null) {
18719                            app.adjType = adjType;
18720                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18721                                    .REASON_SERVICE_IN_USE;
18722                            app.adjSource = cr.binding.client;
18723                            app.adjSourceProcState = clientProcState;
18724                            app.adjTarget = s.name;
18725                        }
18726                    }
18727                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18728                        app.treatLikeActivity = true;
18729                    }
18730                    final ActivityRecord a = cr.activity;
18731                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18732                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18733                            (a.visible || a.state == ActivityState.RESUMED ||
18734                             a.state == ActivityState.PAUSING)) {
18735                            adj = ProcessList.FOREGROUND_APP_ADJ;
18736                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18737                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18738                                    schedGroup = Process.THREAD_GROUP_TOP_APP;
18739                                } else {
18740                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18741                                }
18742                            }
18743                            app.cached = false;
18744                            app.adjType = "service";
18745                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18746                                    .REASON_SERVICE_IN_USE;
18747                            app.adjSource = a;
18748                            app.adjSourceProcState = procState;
18749                            app.adjTarget = s.name;
18750                        }
18751                    }
18752                }
18753            }
18754        }
18755
18756        for (int provi = app.pubProviders.size()-1;
18757                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18758                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18759                        || procState > ActivityManager.PROCESS_STATE_TOP);
18760                provi--) {
18761            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18762            for (int i = cpr.connections.size()-1;
18763                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18764                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18765                            || procState > ActivityManager.PROCESS_STATE_TOP);
18766                    i--) {
18767                ContentProviderConnection conn = cpr.connections.get(i);
18768                ProcessRecord client = conn.client;
18769                if (client == app) {
18770                    // Being our own client is not interesting.
18771                    continue;
18772                }
18773                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18774                int clientProcState = client.curProcState;
18775                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18776                    // If the other app is cached for any reason, for purposes here
18777                    // we are going to consider it empty.
18778                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18779                }
18780                if (adj > clientAdj) {
18781                    if (app.hasShownUi && app != mHomeProcess
18782                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18783                        app.adjType = "cch-ui-provider";
18784                    } else {
18785                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18786                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18787                        app.adjType = "provider";
18788                    }
18789                    app.cached &= client.cached;
18790                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18791                            .REASON_PROVIDER_IN_USE;
18792                    app.adjSource = client;
18793                    app.adjSourceProcState = clientProcState;
18794                    app.adjTarget = cpr.name;
18795                }
18796                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18797                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18798                        // Special handling of clients who are in the top state.
18799                        // We *may* want to consider this process to be in the
18800                        // top state as well, but only if there is not another
18801                        // reason for it to be running.  Being on the top is a
18802                        // special state, meaning you are specifically running
18803                        // for the current top app.  If the process is already
18804                        // running in the background for some other reason, it
18805                        // is more important to continue considering it to be
18806                        // in the background state.
18807                        mayBeTop = true;
18808                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18809                    } else {
18810                        // Special handling for above-top states (persistent
18811                        // processes).  These should not bring the current process
18812                        // into the top state, since they are not on top.  Instead
18813                        // give them the best state after that.
18814                        clientProcState =
18815                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18816                    }
18817                }
18818                if (procState > clientProcState) {
18819                    procState = clientProcState;
18820                }
18821                if (client.curSchedGroup > schedGroup) {
18822                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18823                }
18824            }
18825            // If the provider has external (non-framework) process
18826            // dependencies, ensure that its adjustment is at least
18827            // FOREGROUND_APP_ADJ.
18828            if (cpr.hasExternalProcessHandles()) {
18829                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18830                    adj = ProcessList.FOREGROUND_APP_ADJ;
18831                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18832                    app.cached = false;
18833                    app.adjType = "provider";
18834                    app.adjTarget = cpr.name;
18835                }
18836                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18837                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18838                }
18839            }
18840        }
18841
18842        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18843            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18844                adj = ProcessList.PREVIOUS_APP_ADJ;
18845                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18846                app.cached = false;
18847                app.adjType = "provider";
18848            }
18849            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18850                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18851            }
18852        }
18853
18854        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18855            // A client of one of our services or providers is in the top state.  We
18856            // *may* want to be in the top state, but not if we are already running in
18857            // the background for some other reason.  For the decision here, we are going
18858            // to pick out a few specific states that we want to remain in when a client
18859            // is top (states that tend to be longer-term) and otherwise allow it to go
18860            // to the top state.
18861            switch (procState) {
18862                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18863                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18864                case ActivityManager.PROCESS_STATE_SERVICE:
18865                    // These all are longer-term states, so pull them up to the top
18866                    // of the background states, but not all the way to the top state.
18867                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18868                    break;
18869                default:
18870                    // Otherwise, top is a better choice, so take it.
18871                    procState = ActivityManager.PROCESS_STATE_TOP;
18872                    break;
18873            }
18874        }
18875
18876        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18877            if (app.hasClientActivities) {
18878                // This is a cached process, but with client activities.  Mark it so.
18879                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18880                app.adjType = "cch-client-act";
18881            } else if (app.treatLikeActivity) {
18882                // This is a cached process, but somebody wants us to treat it like it has
18883                // an activity, okay!
18884                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18885                app.adjType = "cch-as-act";
18886            }
18887        }
18888
18889        if (adj == ProcessList.SERVICE_ADJ) {
18890            if (doingAll) {
18891                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18892                mNewNumServiceProcs++;
18893                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18894                if (!app.serviceb) {
18895                    // This service isn't far enough down on the LRU list to
18896                    // normally be a B service, but if we are low on RAM and it
18897                    // is large we want to force it down since we would prefer to
18898                    // keep launcher over it.
18899                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18900                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18901                        app.serviceHighRam = true;
18902                        app.serviceb = true;
18903                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18904                    } else {
18905                        mNewNumAServiceProcs++;
18906                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18907                    }
18908                } else {
18909                    app.serviceHighRam = false;
18910                }
18911            }
18912            if (app.serviceb) {
18913                adj = ProcessList.SERVICE_B_ADJ;
18914            }
18915        }
18916
18917        app.curRawAdj = adj;
18918
18919        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18920        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18921        if (adj > app.maxAdj) {
18922            adj = app.maxAdj;
18923            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18924                schedGroup = Process.THREAD_GROUP_DEFAULT;
18925            }
18926        }
18927
18928        // Do final modification to adj.  Everything we do between here and applying
18929        // the final setAdj must be done in this function, because we will also use
18930        // it when computing the final cached adj later.  Note that we don't need to
18931        // worry about this for max adj above, since max adj will always be used to
18932        // keep it out of the cached vaues.
18933        app.curAdj = app.modifyRawOomAdj(adj);
18934        app.curSchedGroup = schedGroup;
18935        app.curProcState = procState;
18936        app.foregroundActivities = foregroundActivities;
18937
18938        return app.curRawAdj;
18939    }
18940
18941    /**
18942     * Record new PSS sample for a process.
18943     */
18944    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
18945            long now) {
18946        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
18947                swapPss * 1024);
18948        proc.lastPssTime = now;
18949        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18950        if (DEBUG_PSS) Slog.d(TAG_PSS,
18951                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18952                + " state=" + ProcessList.makeProcStateString(procState));
18953        if (proc.initialIdlePss == 0) {
18954            proc.initialIdlePss = pss;
18955        }
18956        proc.lastPss = pss;
18957        proc.lastSwapPss = swapPss;
18958        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18959            proc.lastCachedPss = pss;
18960            proc.lastCachedSwapPss = swapPss;
18961        }
18962
18963        final SparseArray<Pair<Long, String>> watchUids
18964                = mMemWatchProcesses.getMap().get(proc.processName);
18965        Long check = null;
18966        if (watchUids != null) {
18967            Pair<Long, String> val = watchUids.get(proc.uid);
18968            if (val == null) {
18969                val = watchUids.get(0);
18970            }
18971            if (val != null) {
18972                check = val.first;
18973            }
18974        }
18975        if (check != null) {
18976            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18977                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18978                if (!isDebuggable) {
18979                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18980                        isDebuggable = true;
18981                    }
18982                }
18983                if (isDebuggable) {
18984                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18985                    final ProcessRecord myProc = proc;
18986                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18987                    mMemWatchDumpProcName = proc.processName;
18988                    mMemWatchDumpFile = heapdumpFile.toString();
18989                    mMemWatchDumpPid = proc.pid;
18990                    mMemWatchDumpUid = proc.uid;
18991                    BackgroundThread.getHandler().post(new Runnable() {
18992                        @Override
18993                        public void run() {
18994                            revokeUriPermission(ActivityThread.currentActivityThread()
18995                                            .getApplicationThread(),
18996                                    DumpHeapActivity.JAVA_URI,
18997                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18998                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18999                                    UserHandle.myUserId());
19000                            ParcelFileDescriptor fd = null;
19001                            try {
19002                                heapdumpFile.delete();
19003                                fd = ParcelFileDescriptor.open(heapdumpFile,
19004                                        ParcelFileDescriptor.MODE_CREATE |
19005                                                ParcelFileDescriptor.MODE_TRUNCATE |
19006                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19007                                                ParcelFileDescriptor.MODE_APPEND);
19008                                IApplicationThread thread = myProc.thread;
19009                                if (thread != null) {
19010                                    try {
19011                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19012                                                "Requesting dump heap from "
19013                                                + myProc + " to " + heapdumpFile);
19014                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19015                                    } catch (RemoteException e) {
19016                                    }
19017                                }
19018                            } catch (FileNotFoundException e) {
19019                                e.printStackTrace();
19020                            } finally {
19021                                if (fd != null) {
19022                                    try {
19023                                        fd.close();
19024                                    } catch (IOException e) {
19025                                    }
19026                                }
19027                            }
19028                        }
19029                    });
19030                } else {
19031                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19032                            + ", but debugging not enabled");
19033                }
19034            }
19035        }
19036    }
19037
19038    /**
19039     * Schedule PSS collection of a process.
19040     */
19041    void requestPssLocked(ProcessRecord proc, int procState) {
19042        if (mPendingPssProcesses.contains(proc)) {
19043            return;
19044        }
19045        if (mPendingPssProcesses.size() == 0) {
19046            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19047        }
19048        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19049        proc.pssProcState = procState;
19050        mPendingPssProcesses.add(proc);
19051    }
19052
19053    /**
19054     * Schedule PSS collection of all processes.
19055     */
19056    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19057        if (!always) {
19058            if (now < (mLastFullPssTime +
19059                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19060                return;
19061            }
19062        }
19063        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19064        mLastFullPssTime = now;
19065        mFullPssPending = true;
19066        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19067        mPendingPssProcesses.clear();
19068        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19069            ProcessRecord app = mLruProcesses.get(i);
19070            if (app.thread == null
19071                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19072                continue;
19073            }
19074            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19075                app.pssProcState = app.setProcState;
19076                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19077                        mTestPssMode, isSleeping(), now);
19078                mPendingPssProcesses.add(app);
19079            }
19080        }
19081        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19082    }
19083
19084    public void setTestPssMode(boolean enabled) {
19085        synchronized (this) {
19086            mTestPssMode = enabled;
19087            if (enabled) {
19088                // Whenever we enable the mode, we want to take a snapshot all of current
19089                // process mem use.
19090                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19091            }
19092        }
19093    }
19094
19095    /**
19096     * Ask a given process to GC right now.
19097     */
19098    final void performAppGcLocked(ProcessRecord app) {
19099        try {
19100            app.lastRequestedGc = SystemClock.uptimeMillis();
19101            if (app.thread != null) {
19102                if (app.reportLowMemory) {
19103                    app.reportLowMemory = false;
19104                    app.thread.scheduleLowMemory();
19105                } else {
19106                    app.thread.processInBackground();
19107                }
19108            }
19109        } catch (Exception e) {
19110            // whatever.
19111        }
19112    }
19113
19114    /**
19115     * Returns true if things are idle enough to perform GCs.
19116     */
19117    private final boolean canGcNowLocked() {
19118        boolean processingBroadcasts = false;
19119        for (BroadcastQueue q : mBroadcastQueues) {
19120            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19121                processingBroadcasts = true;
19122            }
19123        }
19124        return !processingBroadcasts
19125                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19126    }
19127
19128    /**
19129     * Perform GCs on all processes that are waiting for it, but only
19130     * if things are idle.
19131     */
19132    final void performAppGcsLocked() {
19133        final int N = mProcessesToGc.size();
19134        if (N <= 0) {
19135            return;
19136        }
19137        if (canGcNowLocked()) {
19138            while (mProcessesToGc.size() > 0) {
19139                ProcessRecord proc = mProcessesToGc.remove(0);
19140                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19141                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19142                            <= SystemClock.uptimeMillis()) {
19143                        // To avoid spamming the system, we will GC processes one
19144                        // at a time, waiting a few seconds between each.
19145                        performAppGcLocked(proc);
19146                        scheduleAppGcsLocked();
19147                        return;
19148                    } else {
19149                        // It hasn't been long enough since we last GCed this
19150                        // process...  put it in the list to wait for its time.
19151                        addProcessToGcListLocked(proc);
19152                        break;
19153                    }
19154                }
19155            }
19156
19157            scheduleAppGcsLocked();
19158        }
19159    }
19160
19161    /**
19162     * If all looks good, perform GCs on all processes waiting for them.
19163     */
19164    final void performAppGcsIfAppropriateLocked() {
19165        if (canGcNowLocked()) {
19166            performAppGcsLocked();
19167            return;
19168        }
19169        // Still not idle, wait some more.
19170        scheduleAppGcsLocked();
19171    }
19172
19173    /**
19174     * Schedule the execution of all pending app GCs.
19175     */
19176    final void scheduleAppGcsLocked() {
19177        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19178
19179        if (mProcessesToGc.size() > 0) {
19180            // Schedule a GC for the time to the next process.
19181            ProcessRecord proc = mProcessesToGc.get(0);
19182            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19183
19184            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19185            long now = SystemClock.uptimeMillis();
19186            if (when < (now+GC_TIMEOUT)) {
19187                when = now + GC_TIMEOUT;
19188            }
19189            mHandler.sendMessageAtTime(msg, when);
19190        }
19191    }
19192
19193    /**
19194     * Add a process to the array of processes waiting to be GCed.  Keeps the
19195     * list in sorted order by the last GC time.  The process can't already be
19196     * on the list.
19197     */
19198    final void addProcessToGcListLocked(ProcessRecord proc) {
19199        boolean added = false;
19200        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19201            if (mProcessesToGc.get(i).lastRequestedGc <
19202                    proc.lastRequestedGc) {
19203                added = true;
19204                mProcessesToGc.add(i+1, proc);
19205                break;
19206            }
19207        }
19208        if (!added) {
19209            mProcessesToGc.add(0, proc);
19210        }
19211    }
19212
19213    /**
19214     * Set up to ask a process to GC itself.  This will either do it
19215     * immediately, or put it on the list of processes to gc the next
19216     * time things are idle.
19217     */
19218    final void scheduleAppGcLocked(ProcessRecord app) {
19219        long now = SystemClock.uptimeMillis();
19220        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19221            return;
19222        }
19223        if (!mProcessesToGc.contains(app)) {
19224            addProcessToGcListLocked(app);
19225            scheduleAppGcsLocked();
19226        }
19227    }
19228
19229    final void checkExcessivePowerUsageLocked(boolean doKills) {
19230        updateCpuStatsNow();
19231
19232        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19233        boolean doWakeKills = doKills;
19234        boolean doCpuKills = doKills;
19235        if (mLastPowerCheckRealtime == 0) {
19236            doWakeKills = false;
19237        }
19238        if (mLastPowerCheckUptime == 0) {
19239            doCpuKills = false;
19240        }
19241        if (stats.isScreenOn()) {
19242            doWakeKills = false;
19243        }
19244        final long curRealtime = SystemClock.elapsedRealtime();
19245        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19246        final long curUptime = SystemClock.uptimeMillis();
19247        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19248        mLastPowerCheckRealtime = curRealtime;
19249        mLastPowerCheckUptime = curUptime;
19250        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19251            doWakeKills = false;
19252        }
19253        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19254            doCpuKills = false;
19255        }
19256        int i = mLruProcesses.size();
19257        while (i > 0) {
19258            i--;
19259            ProcessRecord app = mLruProcesses.get(i);
19260            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19261                long wtime;
19262                synchronized (stats) {
19263                    wtime = stats.getProcessWakeTime(app.info.uid,
19264                            app.pid, curRealtime);
19265                }
19266                long wtimeUsed = wtime - app.lastWakeTime;
19267                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19268                if (DEBUG_POWER) {
19269                    StringBuilder sb = new StringBuilder(128);
19270                    sb.append("Wake for ");
19271                    app.toShortString(sb);
19272                    sb.append(": over ");
19273                    TimeUtils.formatDuration(realtimeSince, sb);
19274                    sb.append(" used ");
19275                    TimeUtils.formatDuration(wtimeUsed, sb);
19276                    sb.append(" (");
19277                    sb.append((wtimeUsed*100)/realtimeSince);
19278                    sb.append("%)");
19279                    Slog.i(TAG_POWER, sb.toString());
19280                    sb.setLength(0);
19281                    sb.append("CPU for ");
19282                    app.toShortString(sb);
19283                    sb.append(": over ");
19284                    TimeUtils.formatDuration(uptimeSince, sb);
19285                    sb.append(" used ");
19286                    TimeUtils.formatDuration(cputimeUsed, sb);
19287                    sb.append(" (");
19288                    sb.append((cputimeUsed*100)/uptimeSince);
19289                    sb.append("%)");
19290                    Slog.i(TAG_POWER, sb.toString());
19291                }
19292                // If a process has held a wake lock for more
19293                // than 50% of the time during this period,
19294                // that sounds bad.  Kill!
19295                if (doWakeKills && realtimeSince > 0
19296                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19297                    synchronized (stats) {
19298                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19299                                realtimeSince, wtimeUsed);
19300                    }
19301                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19302                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19303                } else if (doCpuKills && uptimeSince > 0
19304                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19305                    synchronized (stats) {
19306                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19307                                uptimeSince, cputimeUsed);
19308                    }
19309                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19310                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19311                } else {
19312                    app.lastWakeTime = wtime;
19313                    app.lastCpuTime = app.curCpuTime;
19314                }
19315            }
19316        }
19317    }
19318
19319    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19320            long nowElapsed) {
19321        boolean success = true;
19322
19323        if (app.curRawAdj != app.setRawAdj) {
19324            app.setRawAdj = app.curRawAdj;
19325        }
19326
19327        int changes = 0;
19328
19329        if (app.curAdj != app.setAdj) {
19330            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19331            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19332                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19333                    + app.adjType);
19334            app.setAdj = app.curAdj;
19335        }
19336
19337        if (app.setSchedGroup != app.curSchedGroup) {
19338            app.setSchedGroup = app.curSchedGroup;
19339            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19340                    "Setting process group of " + app.processName
19341                    + " to " + app.curSchedGroup);
19342            if (app.waitingToKill != null && app.curReceiver == null
19343                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19344                app.kill(app.waitingToKill, true);
19345                success = false;
19346            } else {
19347                if (true) {
19348                    long oldId = Binder.clearCallingIdentity();
19349                    try {
19350                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19351                    } catch (Exception e) {
19352                        Slog.w(TAG, "Failed setting process group of " + app.pid
19353                                + " to " + app.curSchedGroup);
19354                        e.printStackTrace();
19355                    } finally {
19356                        Binder.restoreCallingIdentity(oldId);
19357                    }
19358                } else {
19359                    if (app.thread != null) {
19360                        try {
19361                            app.thread.setSchedulingGroup(app.curSchedGroup);
19362                        } catch (RemoteException e) {
19363                        }
19364                    }
19365                }
19366            }
19367        }
19368        if (app.repForegroundActivities != app.foregroundActivities) {
19369            app.repForegroundActivities = app.foregroundActivities;
19370            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19371        }
19372        if (app.repProcState != app.curProcState) {
19373            app.repProcState = app.curProcState;
19374            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19375            if (app.thread != null) {
19376                try {
19377                    if (false) {
19378                        //RuntimeException h = new RuntimeException("here");
19379                        Slog.i(TAG, "Sending new process state " + app.repProcState
19380                                + " to " + app /*, h*/);
19381                    }
19382                    app.thread.setProcessState(app.repProcState);
19383                } catch (RemoteException e) {
19384                }
19385            }
19386        }
19387        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19388                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19389            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19390                // Experimental code to more aggressively collect pss while
19391                // running test...  the problem is that this tends to collect
19392                // the data right when a process is transitioning between process
19393                // states, which well tend to give noisy data.
19394                long start = SystemClock.uptimeMillis();
19395                long pss = Debug.getPss(app.pid, mTmpLong, null);
19396                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19397                mPendingPssProcesses.remove(app);
19398                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19399                        + " to " + app.curProcState + ": "
19400                        + (SystemClock.uptimeMillis()-start) + "ms");
19401            }
19402            app.lastStateTime = now;
19403            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19404                    mTestPssMode, isSleeping(), now);
19405            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19406                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19407                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19408                    + (app.nextPssTime-now) + ": " + app);
19409        } else {
19410            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19411                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19412                    mTestPssMode)))) {
19413                requestPssLocked(app, app.setProcState);
19414                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19415                        mTestPssMode, isSleeping(), now);
19416            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19417                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19418        }
19419        if (app.setProcState != app.curProcState) {
19420            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19421                    "Proc state change of " + app.processName
19422                            + " to " + app.curProcState);
19423            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19424            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19425            if (setImportant && !curImportant) {
19426                // This app is no longer something we consider important enough to allow to
19427                // use arbitrary amounts of battery power.  Note
19428                // its current wake lock time to later know to kill it if
19429                // it is not behaving well.
19430                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19431                synchronized (stats) {
19432                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19433                            app.pid, nowElapsed);
19434                }
19435                app.lastCpuTime = app.curCpuTime;
19436
19437            }
19438            // Inform UsageStats of important process state change
19439            // Must be called before updating setProcState
19440            maybeUpdateUsageStatsLocked(app, nowElapsed);
19441
19442            app.setProcState = app.curProcState;
19443            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19444                app.notCachedSinceIdle = false;
19445            }
19446            if (!doingAll) {
19447                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19448            } else {
19449                app.procStateChanged = true;
19450            }
19451        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19452                > USAGE_STATS_INTERACTION_INTERVAL) {
19453            // For apps that sit around for a long time in the interactive state, we need
19454            // to report this at least once a day so they don't go idle.
19455            maybeUpdateUsageStatsLocked(app, nowElapsed);
19456        }
19457
19458        if (changes != 0) {
19459            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19460                    "Changes in " + app + ": " + changes);
19461            int i = mPendingProcessChanges.size()-1;
19462            ProcessChangeItem item = null;
19463            while (i >= 0) {
19464                item = mPendingProcessChanges.get(i);
19465                if (item.pid == app.pid) {
19466                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19467                            "Re-using existing item: " + item);
19468                    break;
19469                }
19470                i--;
19471            }
19472            if (i < 0) {
19473                // No existing item in pending changes; need a new one.
19474                final int NA = mAvailProcessChanges.size();
19475                if (NA > 0) {
19476                    item = mAvailProcessChanges.remove(NA-1);
19477                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19478                            "Retrieving available item: " + item);
19479                } else {
19480                    item = new ProcessChangeItem();
19481                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19482                            "Allocating new item: " + item);
19483                }
19484                item.changes = 0;
19485                item.pid = app.pid;
19486                item.uid = app.info.uid;
19487                if (mPendingProcessChanges.size() == 0) {
19488                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19489                            "*** Enqueueing dispatch processes changed!");
19490                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19491                }
19492                mPendingProcessChanges.add(item);
19493            }
19494            item.changes |= changes;
19495            item.processState = app.repProcState;
19496            item.foregroundActivities = app.repForegroundActivities;
19497            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19498                    "Item " + Integer.toHexString(System.identityHashCode(item))
19499                    + " " + app.toShortString() + ": changes=" + item.changes
19500                    + " procState=" + item.processState
19501                    + " foreground=" + item.foregroundActivities
19502                    + " type=" + app.adjType + " source=" + app.adjSource
19503                    + " target=" + app.adjTarget);
19504        }
19505
19506        return success;
19507    }
19508
19509    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19510        final UidRecord.ChangeItem pendingChange;
19511        if (uidRec == null || uidRec.pendingChange == null) {
19512            if (mPendingUidChanges.size() == 0) {
19513                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19514                        "*** Enqueueing dispatch uid changed!");
19515                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19516            }
19517            final int NA = mAvailUidChanges.size();
19518            if (NA > 0) {
19519                pendingChange = mAvailUidChanges.remove(NA-1);
19520                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19521                        "Retrieving available item: " + pendingChange);
19522            } else {
19523                pendingChange = new UidRecord.ChangeItem();
19524                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19525                        "Allocating new item: " + pendingChange);
19526            }
19527            if (uidRec != null) {
19528                uidRec.pendingChange = pendingChange;
19529                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19530                    // If this uid is going away, and we haven't yet reported it is gone,
19531                    // then do so now.
19532                    change = UidRecord.CHANGE_GONE_IDLE;
19533                }
19534            } else if (uid < 0) {
19535                throw new IllegalArgumentException("No UidRecord or uid");
19536            }
19537            pendingChange.uidRecord = uidRec;
19538            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19539            mPendingUidChanges.add(pendingChange);
19540        } else {
19541            pendingChange = uidRec.pendingChange;
19542            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19543                change = UidRecord.CHANGE_GONE_IDLE;
19544            }
19545        }
19546        pendingChange.change = change;
19547        pendingChange.processState = uidRec != null
19548                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19549    }
19550
19551    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19552            String authority) {
19553        if (app == null) return;
19554        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19555            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19556            if (userState == null) return;
19557            final long now = SystemClock.elapsedRealtime();
19558            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19559            if (lastReported == null || lastReported < now - 60 * 1000L) {
19560                mUsageStatsService.reportContentProviderUsage(
19561                        authority, providerPkgName, app.userId);
19562                userState.mProviderLastReportedFg.put(authority, now);
19563            }
19564        }
19565    }
19566
19567    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19568        if (DEBUG_USAGE_STATS) {
19569            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19570                    + "] state changes: old = " + app.setProcState + ", new = "
19571                    + app.curProcState);
19572        }
19573        if (mUsageStatsService == null) {
19574            return;
19575        }
19576        boolean isInteraction;
19577        // To avoid some abuse patterns, we are going to be careful about what we consider
19578        // to be an app interaction.  Being the top activity doesn't count while the display
19579        // is sleeping, nor do short foreground services.
19580        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19581            isInteraction = true;
19582            app.fgInteractionTime = 0;
19583        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19584            if (app.fgInteractionTime == 0) {
19585                app.fgInteractionTime = nowElapsed;
19586                isInteraction = false;
19587            } else {
19588                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19589            }
19590        } else {
19591            isInteraction = app.curProcState
19592                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19593            app.fgInteractionTime = 0;
19594        }
19595        if (isInteraction && (!app.reportedInteraction
19596                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19597            app.interactionEventTime = nowElapsed;
19598            String[] packages = app.getPackageList();
19599            if (packages != null) {
19600                for (int i = 0; i < packages.length; i++) {
19601                    mUsageStatsService.reportEvent(packages[i], app.userId,
19602                            UsageEvents.Event.SYSTEM_INTERACTION);
19603                }
19604            }
19605        }
19606        app.reportedInteraction = isInteraction;
19607        if (!isInteraction) {
19608            app.interactionEventTime = 0;
19609        }
19610    }
19611
19612    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19613        if (proc.thread != null) {
19614            if (proc.baseProcessTracker != null) {
19615                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19616            }
19617        }
19618    }
19619
19620    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19621            ProcessRecord TOP_APP, boolean doingAll, long now) {
19622        if (app.thread == null) {
19623            return false;
19624        }
19625
19626        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19627
19628        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19629    }
19630
19631    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19632            boolean oomAdj) {
19633        if (isForeground != proc.foregroundServices) {
19634            proc.foregroundServices = isForeground;
19635            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19636                    proc.info.uid);
19637            if (isForeground) {
19638                if (curProcs == null) {
19639                    curProcs = new ArrayList<ProcessRecord>();
19640                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19641                }
19642                if (!curProcs.contains(proc)) {
19643                    curProcs.add(proc);
19644                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19645                            proc.info.packageName, proc.info.uid);
19646                }
19647            } else {
19648                if (curProcs != null) {
19649                    if (curProcs.remove(proc)) {
19650                        mBatteryStatsService.noteEvent(
19651                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19652                                proc.info.packageName, proc.info.uid);
19653                        if (curProcs.size() <= 0) {
19654                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19655                        }
19656                    }
19657                }
19658            }
19659            if (oomAdj) {
19660                updateOomAdjLocked();
19661            }
19662        }
19663    }
19664
19665    private final ActivityRecord resumedAppLocked() {
19666        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19667        String pkg;
19668        int uid;
19669        if (act != null) {
19670            pkg = act.packageName;
19671            uid = act.info.applicationInfo.uid;
19672        } else {
19673            pkg = null;
19674            uid = -1;
19675        }
19676        // Has the UID or resumed package name changed?
19677        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19678                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19679            if (mCurResumedPackage != null) {
19680                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19681                        mCurResumedPackage, mCurResumedUid);
19682            }
19683            mCurResumedPackage = pkg;
19684            mCurResumedUid = uid;
19685            if (mCurResumedPackage != null) {
19686                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19687                        mCurResumedPackage, mCurResumedUid);
19688            }
19689        }
19690        return act;
19691    }
19692
19693    final boolean updateOomAdjLocked(ProcessRecord app) {
19694        final ActivityRecord TOP_ACT = resumedAppLocked();
19695        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19696        final boolean wasCached = app.cached;
19697
19698        mAdjSeq++;
19699
19700        // This is the desired cached adjusment we want to tell it to use.
19701        // If our app is currently cached, we know it, and that is it.  Otherwise,
19702        // we don't know it yet, and it needs to now be cached we will then
19703        // need to do a complete oom adj.
19704        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19705                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19706        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19707                SystemClock.uptimeMillis());
19708        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19709            // Changed to/from cached state, so apps after it in the LRU
19710            // list may also be changed.
19711            updateOomAdjLocked();
19712        }
19713        return success;
19714    }
19715
19716    final void updateOomAdjLocked() {
19717        final ActivityRecord TOP_ACT = resumedAppLocked();
19718        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19719        final long now = SystemClock.uptimeMillis();
19720        final long nowElapsed = SystemClock.elapsedRealtime();
19721        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19722        final int N = mLruProcesses.size();
19723
19724        if (false) {
19725            RuntimeException e = new RuntimeException();
19726            e.fillInStackTrace();
19727            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19728        }
19729
19730        // Reset state in all uid records.
19731        for (int i=mActiveUids.size()-1; i>=0; i--) {
19732            final UidRecord uidRec = mActiveUids.valueAt(i);
19733            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19734                    "Starting update of " + uidRec);
19735            uidRec.reset();
19736        }
19737
19738        mStackSupervisor.rankTaskLayersIfNeeded();
19739
19740        mAdjSeq++;
19741        mNewNumServiceProcs = 0;
19742        mNewNumAServiceProcs = 0;
19743
19744        final int emptyProcessLimit;
19745        final int cachedProcessLimit;
19746        if (mProcessLimit <= 0) {
19747            emptyProcessLimit = cachedProcessLimit = 0;
19748        } else if (mProcessLimit == 1) {
19749            emptyProcessLimit = 1;
19750            cachedProcessLimit = 0;
19751        } else {
19752            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19753            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19754        }
19755
19756        // Let's determine how many processes we have running vs.
19757        // how many slots we have for background processes; we may want
19758        // to put multiple processes in a slot of there are enough of
19759        // them.
19760        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19761                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19762        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19763        if (numEmptyProcs > cachedProcessLimit) {
19764            // If there are more empty processes than our limit on cached
19765            // processes, then use the cached process limit for the factor.
19766            // This ensures that the really old empty processes get pushed
19767            // down to the bottom, so if we are running low on memory we will
19768            // have a better chance at keeping around more cached processes
19769            // instead of a gazillion empty processes.
19770            numEmptyProcs = cachedProcessLimit;
19771        }
19772        int emptyFactor = numEmptyProcs/numSlots;
19773        if (emptyFactor < 1) emptyFactor = 1;
19774        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19775        if (cachedFactor < 1) cachedFactor = 1;
19776        int stepCached = 0;
19777        int stepEmpty = 0;
19778        int numCached = 0;
19779        int numEmpty = 0;
19780        int numTrimming = 0;
19781
19782        mNumNonCachedProcs = 0;
19783        mNumCachedHiddenProcs = 0;
19784
19785        // First update the OOM adjustment for each of the
19786        // application processes based on their current state.
19787        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19788        int nextCachedAdj = curCachedAdj+1;
19789        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19790        int nextEmptyAdj = curEmptyAdj+2;
19791        for (int i=N-1; i>=0; i--) {
19792            ProcessRecord app = mLruProcesses.get(i);
19793            if (!app.killedByAm && app.thread != null) {
19794                app.procStateChanged = false;
19795                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19796
19797                // If we haven't yet assigned the final cached adj
19798                // to the process, do that now.
19799                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19800                    switch (app.curProcState) {
19801                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19802                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19803                            // This process is a cached process holding activities...
19804                            // assign it the next cached value for that type, and then
19805                            // step that cached level.
19806                            app.curRawAdj = curCachedAdj;
19807                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19808                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19809                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19810                                    + ")");
19811                            if (curCachedAdj != nextCachedAdj) {
19812                                stepCached++;
19813                                if (stepCached >= cachedFactor) {
19814                                    stepCached = 0;
19815                                    curCachedAdj = nextCachedAdj;
19816                                    nextCachedAdj += 2;
19817                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19818                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19819                                    }
19820                                }
19821                            }
19822                            break;
19823                        default:
19824                            // For everything else, assign next empty cached process
19825                            // level and bump that up.  Note that this means that
19826                            // long-running services that have dropped down to the
19827                            // cached level will be treated as empty (since their process
19828                            // state is still as a service), which is what we want.
19829                            app.curRawAdj = curEmptyAdj;
19830                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19831                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19832                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19833                                    + ")");
19834                            if (curEmptyAdj != nextEmptyAdj) {
19835                                stepEmpty++;
19836                                if (stepEmpty >= emptyFactor) {
19837                                    stepEmpty = 0;
19838                                    curEmptyAdj = nextEmptyAdj;
19839                                    nextEmptyAdj += 2;
19840                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19841                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19842                                    }
19843                                }
19844                            }
19845                            break;
19846                    }
19847                }
19848
19849                applyOomAdjLocked(app, true, now, nowElapsed);
19850
19851                // Count the number of process types.
19852                switch (app.curProcState) {
19853                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19854                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19855                        mNumCachedHiddenProcs++;
19856                        numCached++;
19857                        if (numCached > cachedProcessLimit) {
19858                            app.kill("cached #" + numCached, true);
19859                        }
19860                        break;
19861                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19862                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19863                                && app.lastActivityTime < oldTime) {
19864                            app.kill("empty for "
19865                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19866                                    / 1000) + "s", true);
19867                        } else {
19868                            numEmpty++;
19869                            if (numEmpty > emptyProcessLimit) {
19870                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
19871                            }
19872                        }
19873                        break;
19874                    default:
19875                        mNumNonCachedProcs++;
19876                        break;
19877                }
19878
19879                if (app.isolated && app.services.size() <= 0) {
19880                    // If this is an isolated process, and there are no
19881                    // services running in it, then the process is no longer
19882                    // needed.  We agressively kill these because we can by
19883                    // definition not re-use the same process again, and it is
19884                    // good to avoid having whatever code was running in them
19885                    // left sitting around after no longer needed.
19886                    app.kill("isolated not needed", true);
19887                } else {
19888                    // Keeping this process, update its uid.
19889                    final UidRecord uidRec = app.uidRecord;
19890                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19891                        uidRec.curProcState = app.curProcState;
19892                    }
19893                }
19894
19895                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19896                        && !app.killedByAm) {
19897                    numTrimming++;
19898                }
19899            }
19900        }
19901
19902        mNumServiceProcs = mNewNumServiceProcs;
19903
19904        // Now determine the memory trimming level of background processes.
19905        // Unfortunately we need to start at the back of the list to do this
19906        // properly.  We only do this if the number of background apps we
19907        // are managing to keep around is less than half the maximum we desire;
19908        // if we are keeping a good number around, we'll let them use whatever
19909        // memory they want.
19910        final int numCachedAndEmpty = numCached + numEmpty;
19911        int memFactor;
19912        if (numCached <= ProcessList.TRIM_CACHED_APPS
19913                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19914            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19915                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19916            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19917                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19918            } else {
19919                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19920            }
19921        } else {
19922            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19923        }
19924        // We always allow the memory level to go up (better).  We only allow it to go
19925        // down if we are in a state where that is allowed, *and* the total number of processes
19926        // has gone down since last time.
19927        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19928                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19929                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19930        if (memFactor > mLastMemoryLevel) {
19931            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19932                memFactor = mLastMemoryLevel;
19933                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19934            }
19935        }
19936        mLastMemoryLevel = memFactor;
19937        mLastNumProcesses = mLruProcesses.size();
19938        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19939        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19940        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19941            if (mLowRamStartTime == 0) {
19942                mLowRamStartTime = now;
19943            }
19944            int step = 0;
19945            int fgTrimLevel;
19946            switch (memFactor) {
19947                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19948                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19949                    break;
19950                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19951                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19952                    break;
19953                default:
19954                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19955                    break;
19956            }
19957            int factor = numTrimming/3;
19958            int minFactor = 2;
19959            if (mHomeProcess != null) minFactor++;
19960            if (mPreviousProcess != null) minFactor++;
19961            if (factor < minFactor) factor = minFactor;
19962            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19963            for (int i=N-1; i>=0; i--) {
19964                ProcessRecord app = mLruProcesses.get(i);
19965                if (allChanged || app.procStateChanged) {
19966                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19967                    app.procStateChanged = false;
19968                }
19969                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19970                        && !app.killedByAm) {
19971                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19972                        try {
19973                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19974                                    "Trimming memory of " + app.processName + " to " + curLevel);
19975                            app.thread.scheduleTrimMemory(curLevel);
19976                        } catch (RemoteException e) {
19977                        }
19978                        if (false) {
19979                            // For now we won't do this; our memory trimming seems
19980                            // to be good enough at this point that destroying
19981                            // activities causes more harm than good.
19982                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19983                                    && app != mHomeProcess && app != mPreviousProcess) {
19984                                // Need to do this on its own message because the stack may not
19985                                // be in a consistent state at this point.
19986                                // For these apps we will also finish their activities
19987                                // to help them free memory.
19988                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19989                            }
19990                        }
19991                    }
19992                    app.trimMemoryLevel = curLevel;
19993                    step++;
19994                    if (step >= factor) {
19995                        step = 0;
19996                        switch (curLevel) {
19997                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19998                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19999                                break;
20000                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20001                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20002                                break;
20003                        }
20004                    }
20005                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20006                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20007                            && app.thread != null) {
20008                        try {
20009                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20010                                    "Trimming memory of heavy-weight " + app.processName
20011                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20012                            app.thread.scheduleTrimMemory(
20013                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20014                        } catch (RemoteException e) {
20015                        }
20016                    }
20017                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20018                } else {
20019                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20020                            || app.systemNoUi) && app.pendingUiClean) {
20021                        // If this application is now in the background and it
20022                        // had done UI, then give it the special trim level to
20023                        // have it free UI resources.
20024                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20025                        if (app.trimMemoryLevel < level && app.thread != null) {
20026                            try {
20027                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20028                                        "Trimming memory of bg-ui " + app.processName
20029                                        + " to " + level);
20030                                app.thread.scheduleTrimMemory(level);
20031                            } catch (RemoteException e) {
20032                            }
20033                        }
20034                        app.pendingUiClean = false;
20035                    }
20036                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20037                        try {
20038                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20039                                    "Trimming memory of fg " + app.processName
20040                                    + " to " + fgTrimLevel);
20041                            app.thread.scheduleTrimMemory(fgTrimLevel);
20042                        } catch (RemoteException e) {
20043                        }
20044                    }
20045                    app.trimMemoryLevel = fgTrimLevel;
20046                }
20047            }
20048        } else {
20049            if (mLowRamStartTime != 0) {
20050                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20051                mLowRamStartTime = 0;
20052            }
20053            for (int i=N-1; i>=0; i--) {
20054                ProcessRecord app = mLruProcesses.get(i);
20055                if (allChanged || app.procStateChanged) {
20056                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20057                    app.procStateChanged = false;
20058                }
20059                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20060                        || app.systemNoUi) && app.pendingUiClean) {
20061                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20062                            && app.thread != null) {
20063                        try {
20064                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20065                                    "Trimming memory of ui hidden " + app.processName
20066                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20067                            app.thread.scheduleTrimMemory(
20068                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20069                        } catch (RemoteException e) {
20070                        }
20071                    }
20072                    app.pendingUiClean = false;
20073                }
20074                app.trimMemoryLevel = 0;
20075            }
20076        }
20077
20078        if (mAlwaysFinishActivities) {
20079            // Need to do this on its own message because the stack may not
20080            // be in a consistent state at this point.
20081            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20082        }
20083
20084        if (allChanged) {
20085            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20086        }
20087
20088        // Update from any uid changes.
20089        for (int i=mActiveUids.size()-1; i>=0; i--) {
20090            final UidRecord uidRec = mActiveUids.valueAt(i);
20091            int uidChange = UidRecord.CHANGE_PROCSTATE;
20092            if (uidRec.setProcState != uidRec.curProcState) {
20093                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20094                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20095                        + " to " + uidRec.curProcState);
20096                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20097                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20098                        uidRec.lastBackgroundTime = nowElapsed;
20099                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20100                            // Note: the background settle time is in elapsed realtime, while
20101                            // the handler time base is uptime.  All this means is that we may
20102                            // stop background uids later than we had intended, but that only
20103                            // happens because the device was sleeping so we are okay anyway.
20104                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20105                        }
20106                    }
20107                } else {
20108                    if (uidRec.idle) {
20109                        uidChange = UidRecord.CHANGE_ACTIVE;
20110                        uidRec.idle = false;
20111                    }
20112                    uidRec.lastBackgroundTime = 0;
20113                }
20114                uidRec.setProcState = uidRec.curProcState;
20115                enqueueUidChangeLocked(uidRec, -1, uidChange);
20116                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20117            }
20118        }
20119
20120        if (mProcessStats.shouldWriteNowLocked(now)) {
20121            mHandler.post(new Runnable() {
20122                @Override public void run() {
20123                    synchronized (ActivityManagerService.this) {
20124                        mProcessStats.writeStateAsyncLocked();
20125                    }
20126                }
20127            });
20128        }
20129
20130        if (DEBUG_OOM_ADJ) {
20131            final long duration = SystemClock.uptimeMillis() - now;
20132            if (false) {
20133                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20134                        new RuntimeException("here").fillInStackTrace());
20135            } else {
20136                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20137            }
20138        }
20139    }
20140
20141    final void idleUids() {
20142        synchronized (this) {
20143            final long nowElapsed = SystemClock.elapsedRealtime();
20144            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20145            long nextTime = 0;
20146            for (int i=mActiveUids.size()-1; i>=0; i--) {
20147                final UidRecord uidRec = mActiveUids.valueAt(i);
20148                final long bgTime = uidRec.lastBackgroundTime;
20149                if (bgTime > 0 && !uidRec.idle) {
20150                    if (bgTime <= maxBgTime) {
20151                        uidRec.idle = true;
20152                        doStopUidLocked(uidRec.uid, uidRec);
20153                    } else {
20154                        if (nextTime == 0 || nextTime > bgTime) {
20155                            nextTime = bgTime;
20156                        }
20157                    }
20158                }
20159            }
20160            if (nextTime > 0) {
20161                mHandler.removeMessages(IDLE_UIDS_MSG);
20162                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20163                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20164            }
20165        }
20166    }
20167
20168    final void runInBackgroundDisabled(int uid) {
20169        synchronized (this) {
20170            UidRecord uidRec = mActiveUids.get(uid);
20171            if (uidRec != null) {
20172                // This uid is actually running...  should it be considered background now?
20173                if (uidRec.idle) {
20174                    doStopUidLocked(uidRec.uid, uidRec);
20175                }
20176            } else {
20177                // This uid isn't actually running...  still send a report about it being "stopped".
20178                doStopUidLocked(uid, null);
20179            }
20180        }
20181    }
20182
20183    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20184        mServices.stopInBackgroundLocked(uid);
20185        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20186    }
20187
20188    final void trimApplications() {
20189        synchronized (this) {
20190            int i;
20191
20192            // First remove any unused application processes whose package
20193            // has been removed.
20194            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20195                final ProcessRecord app = mRemovedProcesses.get(i);
20196                if (app.activities.size() == 0
20197                        && app.curReceiver == null && app.services.size() == 0) {
20198                    Slog.i(
20199                        TAG, "Exiting empty application process "
20200                        + app.processName + " ("
20201                        + (app.thread != null ? app.thread.asBinder() : null)
20202                        + ")\n");
20203                    if (app.pid > 0 && app.pid != MY_PID) {
20204                        app.kill("empty", false);
20205                    } else {
20206                        try {
20207                            app.thread.scheduleExit();
20208                        } catch (Exception e) {
20209                            // Ignore exceptions.
20210                        }
20211                    }
20212                    cleanUpApplicationRecordLocked(app, false, true, -1);
20213                    mRemovedProcesses.remove(i);
20214
20215                    if (app.persistent) {
20216                        addAppLocked(app.info, false, null /* ABI override */);
20217                    }
20218                }
20219            }
20220
20221            // Now update the oom adj for all processes.
20222            updateOomAdjLocked();
20223        }
20224    }
20225
20226    /** This method sends the specified signal to each of the persistent apps */
20227    public void signalPersistentProcesses(int sig) throws RemoteException {
20228        if (sig != Process.SIGNAL_USR1) {
20229            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20230        }
20231
20232        synchronized (this) {
20233            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20234                    != PackageManager.PERMISSION_GRANTED) {
20235                throw new SecurityException("Requires permission "
20236                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20237            }
20238
20239            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20240                ProcessRecord r = mLruProcesses.get(i);
20241                if (r.thread != null && r.persistent) {
20242                    Process.sendSignal(r.pid, sig);
20243                }
20244            }
20245        }
20246    }
20247
20248    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20249        if (proc == null || proc == mProfileProc) {
20250            proc = mProfileProc;
20251            profileType = mProfileType;
20252            clearProfilerLocked();
20253        }
20254        if (proc == null) {
20255            return;
20256        }
20257        try {
20258            proc.thread.profilerControl(false, null, profileType);
20259        } catch (RemoteException e) {
20260            throw new IllegalStateException("Process disappeared");
20261        }
20262    }
20263
20264    private void clearProfilerLocked() {
20265        if (mProfileFd != null) {
20266            try {
20267                mProfileFd.close();
20268            } catch (IOException e) {
20269            }
20270        }
20271        mProfileApp = null;
20272        mProfileProc = null;
20273        mProfileFile = null;
20274        mProfileType = 0;
20275        mAutoStopProfiler = false;
20276        mSamplingInterval = 0;
20277    }
20278
20279    public boolean profileControl(String process, int userId, boolean start,
20280            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20281
20282        try {
20283            synchronized (this) {
20284                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20285                // its own permission.
20286                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20287                        != PackageManager.PERMISSION_GRANTED) {
20288                    throw new SecurityException("Requires permission "
20289                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20290                }
20291
20292                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20293                    throw new IllegalArgumentException("null profile info or fd");
20294                }
20295
20296                ProcessRecord proc = null;
20297                if (process != null) {
20298                    proc = findProcessLocked(process, userId, "profileControl");
20299                }
20300
20301                if (start && (proc == null || proc.thread == null)) {
20302                    throw new IllegalArgumentException("Unknown process: " + process);
20303                }
20304
20305                if (start) {
20306                    stopProfilerLocked(null, 0);
20307                    setProfileApp(proc.info, proc.processName, profilerInfo);
20308                    mProfileProc = proc;
20309                    mProfileType = profileType;
20310                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20311                    try {
20312                        fd = fd.dup();
20313                    } catch (IOException e) {
20314                        fd = null;
20315                    }
20316                    profilerInfo.profileFd = fd;
20317                    proc.thread.profilerControl(start, profilerInfo, profileType);
20318                    fd = null;
20319                    mProfileFd = null;
20320                } else {
20321                    stopProfilerLocked(proc, profileType);
20322                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20323                        try {
20324                            profilerInfo.profileFd.close();
20325                        } catch (IOException e) {
20326                        }
20327                    }
20328                }
20329
20330                return true;
20331            }
20332        } catch (RemoteException e) {
20333            throw new IllegalStateException("Process disappeared");
20334        } finally {
20335            if (profilerInfo != null && profilerInfo.profileFd != null) {
20336                try {
20337                    profilerInfo.profileFd.close();
20338                } catch (IOException e) {
20339                }
20340            }
20341        }
20342    }
20343
20344    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20345        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20346                userId, true, ALLOW_FULL_ONLY, callName, null);
20347        ProcessRecord proc = null;
20348        try {
20349            int pid = Integer.parseInt(process);
20350            synchronized (mPidsSelfLocked) {
20351                proc = mPidsSelfLocked.get(pid);
20352            }
20353        } catch (NumberFormatException e) {
20354        }
20355
20356        if (proc == null) {
20357            ArrayMap<String, SparseArray<ProcessRecord>> all
20358                    = mProcessNames.getMap();
20359            SparseArray<ProcessRecord> procs = all.get(process);
20360            if (procs != null && procs.size() > 0) {
20361                proc = procs.valueAt(0);
20362                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20363                    for (int i=1; i<procs.size(); i++) {
20364                        ProcessRecord thisProc = procs.valueAt(i);
20365                        if (thisProc.userId == userId) {
20366                            proc = thisProc;
20367                            break;
20368                        }
20369                    }
20370                }
20371            }
20372        }
20373
20374        return proc;
20375    }
20376
20377    public boolean dumpHeap(String process, int userId, boolean managed,
20378            String path, ParcelFileDescriptor fd) throws RemoteException {
20379
20380        try {
20381            synchronized (this) {
20382                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20383                // its own permission (same as profileControl).
20384                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20385                        != PackageManager.PERMISSION_GRANTED) {
20386                    throw new SecurityException("Requires permission "
20387                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20388                }
20389
20390                if (fd == null) {
20391                    throw new IllegalArgumentException("null fd");
20392                }
20393
20394                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20395                if (proc == null || proc.thread == null) {
20396                    throw new IllegalArgumentException("Unknown process: " + process);
20397                }
20398
20399                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20400                if (!isDebuggable) {
20401                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20402                        throw new SecurityException("Process not debuggable: " + proc);
20403                    }
20404                }
20405
20406                proc.thread.dumpHeap(managed, path, fd);
20407                fd = null;
20408                return true;
20409            }
20410        } catch (RemoteException e) {
20411            throw new IllegalStateException("Process disappeared");
20412        } finally {
20413            if (fd != null) {
20414                try {
20415                    fd.close();
20416                } catch (IOException e) {
20417                }
20418            }
20419        }
20420    }
20421
20422    @Override
20423    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20424            String reportPackage) {
20425        if (processName != null) {
20426            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20427                    "setDumpHeapDebugLimit()");
20428        } else {
20429            synchronized (mPidsSelfLocked) {
20430                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20431                if (proc == null) {
20432                    throw new SecurityException("No process found for calling pid "
20433                            + Binder.getCallingPid());
20434                }
20435                if (!Build.IS_DEBUGGABLE
20436                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20437                    throw new SecurityException("Not running a debuggable build");
20438                }
20439                processName = proc.processName;
20440                uid = proc.uid;
20441                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20442                    throw new SecurityException("Package " + reportPackage + " is not running in "
20443                            + proc);
20444                }
20445            }
20446        }
20447        synchronized (this) {
20448            if (maxMemSize > 0) {
20449                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20450            } else {
20451                if (uid != 0) {
20452                    mMemWatchProcesses.remove(processName, uid);
20453                } else {
20454                    mMemWatchProcesses.getMap().remove(processName);
20455                }
20456            }
20457        }
20458    }
20459
20460    @Override
20461    public void dumpHeapFinished(String path) {
20462        synchronized (this) {
20463            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20464                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20465                        + " does not match last pid " + mMemWatchDumpPid);
20466                return;
20467            }
20468            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20469                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20470                        + " does not match last path " + mMemWatchDumpFile);
20471                return;
20472            }
20473            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20474            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20475        }
20476    }
20477
20478    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20479    public void monitor() {
20480        synchronized (this) { }
20481    }
20482
20483    void onCoreSettingsChange(Bundle settings) {
20484        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20485            ProcessRecord processRecord = mLruProcesses.get(i);
20486            try {
20487                if (processRecord.thread != null) {
20488                    processRecord.thread.setCoreSettings(settings);
20489                }
20490            } catch (RemoteException re) {
20491                /* ignore */
20492            }
20493        }
20494    }
20495
20496    // Multi-user methods
20497
20498    /**
20499     * Start user, if its not already running, but don't bring it to foreground.
20500     */
20501    @Override
20502    public boolean startUserInBackground(final int userId) {
20503        return mUserController.startUser(userId, /* foreground */ false);
20504    }
20505
20506    @Override
20507    public boolean unlockUser(int userId, byte[] token, byte[] secret) {
20508        return mUserController.unlockUser(userId, token, secret);
20509    }
20510
20511    @Override
20512    public boolean switchUser(final int targetUserId) {
20513        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20514        UserInfo currentUserInfo;
20515        UserInfo targetUserInfo;
20516        synchronized (this) {
20517            int currentUserId = mUserController.getCurrentUserIdLocked();
20518            currentUserInfo = mUserController.getUserInfo(currentUserId);
20519            targetUserInfo = mUserController.getUserInfo(targetUserId);
20520            if (targetUserInfo == null) {
20521                Slog.w(TAG, "No user info for user #" + targetUserId);
20522                return false;
20523            }
20524            if (!targetUserInfo.supportsSwitchTo()) {
20525                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20526                return false;
20527            }
20528            if (targetUserInfo.isManagedProfile()) {
20529                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20530                return false;
20531            }
20532            mUserController.setTargetUserIdLocked(targetUserId);
20533        }
20534        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20535        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20536        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20537        return true;
20538    }
20539
20540    void scheduleStartProfilesLocked() {
20541        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20542            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20543                    DateUtils.SECOND_IN_MILLIS);
20544        }
20545    }
20546
20547    @Override
20548    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20549        return mUserController.stopUser(userId, force, callback);
20550    }
20551
20552    @Override
20553    public UserInfo getCurrentUser() {
20554        return mUserController.getCurrentUser();
20555    }
20556
20557    @Override
20558    public boolean isUserRunning(int userId, int flags) {
20559        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20560                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20561            String msg = "Permission Denial: isUserRunning() from pid="
20562                    + Binder.getCallingPid()
20563                    + ", uid=" + Binder.getCallingUid()
20564                    + " requires " + INTERACT_ACROSS_USERS;
20565            Slog.w(TAG, msg);
20566            throw new SecurityException(msg);
20567        }
20568        synchronized (this) {
20569            return mUserController.isUserRunningLocked(userId, flags);
20570        }
20571    }
20572
20573    @Override
20574    public int[] getRunningUserIds() {
20575        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20576                != PackageManager.PERMISSION_GRANTED) {
20577            String msg = "Permission Denial: isUserRunning() from pid="
20578                    + Binder.getCallingPid()
20579                    + ", uid=" + Binder.getCallingUid()
20580                    + " requires " + INTERACT_ACROSS_USERS;
20581            Slog.w(TAG, msg);
20582            throw new SecurityException(msg);
20583        }
20584        synchronized (this) {
20585            return mUserController.getStartedUserArrayLocked();
20586        }
20587    }
20588
20589    @Override
20590    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20591        mUserController.registerUserSwitchObserver(observer);
20592    }
20593
20594    @Override
20595    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20596        mUserController.unregisterUserSwitchObserver(observer);
20597    }
20598
20599    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20600        if (info == null) return null;
20601        ApplicationInfo newInfo = new ApplicationInfo(info);
20602        newInfo.initForUser(userId);
20603        return newInfo;
20604    }
20605
20606    public boolean isUserStopped(int userId) {
20607        synchronized (this) {
20608            return mUserController.getStartedUserStateLocked(userId) == null;
20609        }
20610    }
20611
20612    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20613        if (aInfo == null
20614                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20615            return aInfo;
20616        }
20617
20618        ActivityInfo info = new ActivityInfo(aInfo);
20619        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20620        return info;
20621    }
20622
20623    private boolean processSanityChecksLocked(ProcessRecord process) {
20624        if (process == null || process.thread == null) {
20625            return false;
20626        }
20627
20628        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20629        if (!isDebuggable) {
20630            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20631                return false;
20632            }
20633        }
20634
20635        return true;
20636    }
20637
20638    public boolean startBinderTracking() throws RemoteException {
20639        synchronized (this) {
20640            mBinderTransactionTrackingEnabled = true;
20641            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20642            // permission (same as profileControl).
20643            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20644                    != PackageManager.PERMISSION_GRANTED) {
20645                throw new SecurityException("Requires permission "
20646                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20647            }
20648
20649            for (int i = 0; i < mLruProcesses.size(); i++) {
20650                ProcessRecord process = mLruProcesses.get(i);
20651                if (!processSanityChecksLocked(process)) {
20652                    continue;
20653                }
20654                try {
20655                    process.thread.startBinderTracking();
20656                } catch (RemoteException e) {
20657                    Log.v(TAG, "Process disappared");
20658                }
20659            }
20660            return true;
20661        }
20662    }
20663
20664    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20665        try {
20666            synchronized (this) {
20667                mBinderTransactionTrackingEnabled = false;
20668                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20669                // permission (same as profileControl).
20670                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20671                        != PackageManager.PERMISSION_GRANTED) {
20672                    throw new SecurityException("Requires permission "
20673                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20674                }
20675
20676                if (fd == null) {
20677                    throw new IllegalArgumentException("null fd");
20678                }
20679
20680                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20681                pw.println("Binder transaction traces for all processes.\n");
20682                for (ProcessRecord process : mLruProcesses) {
20683                    if (!processSanityChecksLocked(process)) {
20684                        continue;
20685                    }
20686
20687                    pw.println("Traces for process: " + process.processName);
20688                    pw.flush();
20689                    try {
20690                        TransferPipe tp = new TransferPipe();
20691                        try {
20692                            process.thread.stopBinderTrackingAndDump(
20693                                    tp.getWriteFd().getFileDescriptor());
20694                            tp.go(fd.getFileDescriptor());
20695                        } finally {
20696                            tp.kill();
20697                        }
20698                    } catch (IOException e) {
20699                        pw.println("Failure while dumping IPC traces from " + process +
20700                                ".  Exception: " + e);
20701                        pw.flush();
20702                    } catch (RemoteException e) {
20703                        pw.println("Got a RemoteException while dumping IPC traces from " +
20704                                process + ".  Exception: " + e);
20705                        pw.flush();
20706                    }
20707                }
20708                fd = null;
20709                return true;
20710            }
20711        } finally {
20712            if (fd != null) {
20713                try {
20714                    fd.close();
20715                } catch (IOException e) {
20716                }
20717            }
20718        }
20719    }
20720
20721    private final class LocalService extends ActivityManagerInternal {
20722        @Override
20723        public void onWakefulnessChanged(int wakefulness) {
20724            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20725        }
20726
20727        @Override
20728        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20729                String processName, String abiOverride, int uid, Runnable crashHandler) {
20730            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20731                    processName, abiOverride, uid, crashHandler);
20732        }
20733
20734        @Override
20735        public SleepToken acquireSleepToken(String tag) {
20736            Preconditions.checkNotNull(tag);
20737
20738            synchronized (ActivityManagerService.this) {
20739                SleepTokenImpl token = new SleepTokenImpl(tag);
20740                mSleepTokens.add(token);
20741                updateSleepIfNeededLocked();
20742                return token;
20743            }
20744        }
20745
20746        @Override
20747        public ComponentName getHomeActivityForUser(int userId) {
20748            synchronized (ActivityManagerService.this) {
20749                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20750                return homeActivity == null ? null : homeActivity.realActivity;
20751            }
20752        }
20753
20754        @Override
20755        public void onUserRemoved(int userId) {
20756            synchronized (ActivityManagerService.this) {
20757                ActivityManagerService.this.onUserStoppedLocked(userId);
20758            }
20759        }
20760
20761        @Override
20762        public void onLocalVoiceInteractionStarted(IBinder activity,
20763                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20764            synchronized (ActivityManagerService.this) {
20765                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20766                        voiceSession, voiceInteractor);
20767            }
20768        }
20769
20770        @Override
20771        public void notifyStartingWindowDrawn() {
20772            synchronized (ActivityManagerService.this) {
20773                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20774            }
20775        }
20776
20777        @Override
20778        public void notifyAppTransitionStarting(int reason) {
20779            synchronized (ActivityManagerService.this) {
20780                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20781            }
20782        }
20783    }
20784
20785    private final class SleepTokenImpl extends SleepToken {
20786        private final String mTag;
20787        private final long mAcquireTime;
20788
20789        public SleepTokenImpl(String tag) {
20790            mTag = tag;
20791            mAcquireTime = SystemClock.uptimeMillis();
20792        }
20793
20794        @Override
20795        public void release() {
20796            synchronized (ActivityManagerService.this) {
20797                if (mSleepTokens.remove(this)) {
20798                    updateSleepIfNeededLocked();
20799                }
20800            }
20801        }
20802
20803        @Override
20804        public String toString() {
20805            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20806        }
20807    }
20808
20809    /**
20810     * An implementation of IAppTask, that allows an app to manage its own tasks via
20811     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20812     * only the process that calls getAppTasks() can call the AppTask methods.
20813     */
20814    class AppTaskImpl extends IAppTask.Stub {
20815        private int mTaskId;
20816        private int mCallingUid;
20817
20818        public AppTaskImpl(int taskId, int callingUid) {
20819            mTaskId = taskId;
20820            mCallingUid = callingUid;
20821        }
20822
20823        private void checkCaller() {
20824            if (mCallingUid != Binder.getCallingUid()) {
20825                throw new SecurityException("Caller " + mCallingUid
20826                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20827            }
20828        }
20829
20830        @Override
20831        public void finishAndRemoveTask() {
20832            checkCaller();
20833
20834            synchronized (ActivityManagerService.this) {
20835                long origId = Binder.clearCallingIdentity();
20836                try {
20837                    // We remove the task from recents to preserve backwards
20838                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20839                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20840                    }
20841                } finally {
20842                    Binder.restoreCallingIdentity(origId);
20843                }
20844            }
20845        }
20846
20847        @Override
20848        public ActivityManager.RecentTaskInfo getTaskInfo() {
20849            checkCaller();
20850
20851            synchronized (ActivityManagerService.this) {
20852                long origId = Binder.clearCallingIdentity();
20853                try {
20854                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20855                    if (tr == null) {
20856                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20857                    }
20858                    return createRecentTaskInfoFromTaskRecord(tr);
20859                } finally {
20860                    Binder.restoreCallingIdentity(origId);
20861                }
20862            }
20863        }
20864
20865        @Override
20866        public void moveToFront() {
20867            checkCaller();
20868            // Will bring task to front if it already has a root activity.
20869            final long origId = Binder.clearCallingIdentity();
20870            try {
20871                startActivityFromRecentsInner(mTaskId, null);
20872            } finally {
20873                Binder.restoreCallingIdentity(origId);
20874            }
20875        }
20876
20877        @Override
20878        public int startActivity(IBinder whoThread, String callingPackage,
20879                Intent intent, String resolvedType, Bundle bOptions) {
20880            checkCaller();
20881
20882            int callingUser = UserHandle.getCallingUserId();
20883            TaskRecord tr;
20884            IApplicationThread appThread;
20885            synchronized (ActivityManagerService.this) {
20886                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20887                if (tr == null) {
20888                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20889                }
20890                appThread = ApplicationThreadNative.asInterface(whoThread);
20891                if (appThread == null) {
20892                    throw new IllegalArgumentException("Bad app thread " + appThread);
20893                }
20894            }
20895            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
20896                    resolvedType, null, null, null, null, 0, 0, null, null,
20897                    null, bOptions, false, callingUser, null, tr);
20898        }
20899
20900        @Override
20901        public void setExcludeFromRecents(boolean exclude) {
20902            checkCaller();
20903
20904            synchronized (ActivityManagerService.this) {
20905                long origId = Binder.clearCallingIdentity();
20906                try {
20907                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20908                    if (tr == null) {
20909                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20910                    }
20911                    Intent intent = tr.getBaseIntent();
20912                    if (exclude) {
20913                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20914                    } else {
20915                        intent.setFlags(intent.getFlags()
20916                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20917                    }
20918                } finally {
20919                    Binder.restoreCallingIdentity(origId);
20920                }
20921            }
20922        }
20923    }
20924
20925    /**
20926     * Kill processes for the user with id userId and that depend on the package named packageName
20927     */
20928    @Override
20929    public void killPackageDependents(String packageName, int userId) {
20930        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
20931        if (packageName == null) {
20932            throw new NullPointerException(
20933                    "Cannot kill the dependents of a package without its name.");
20934        }
20935
20936        long callingId = Binder.clearCallingIdentity();
20937        IPackageManager pm = AppGlobals.getPackageManager();
20938        int pkgUid = -1;
20939        try {
20940            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
20941        } catch (RemoteException e) {
20942        }
20943        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
20944            throw new IllegalArgumentException(
20945                    "Cannot kill dependents of non-existing package " + packageName);
20946        }
20947        try {
20948            synchronized(this) {
20949                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
20950                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
20951                        "dep: " + packageName);
20952            }
20953        } finally {
20954            Binder.restoreCallingIdentity(callingId);
20955        }
20956    }
20957}
20958