ActivityManagerService.java revision 2aa46d43257ed724298faece0726cebbaff4cbe3
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.net.Proxy;
149import android.net.ProxyInfo;
150import android.net.Uri;
151import android.os.BatteryStats;
152import android.os.Binder;
153import android.os.Build;
154import android.os.Bundle;
155import android.os.Debug;
156import android.os.DropBoxManager;
157import android.os.Environment;
158import android.os.FactoryTest;
159import android.os.FileObserver;
160import android.os.FileUtils;
161import android.os.Handler;
162import android.os.IBinder;
163import android.os.IPermissionController;
164import android.os.IProcessInfoService;
165import android.os.Looper;
166import android.os.Message;
167import android.os.Parcel;
168import android.os.ParcelFileDescriptor;
169import android.os.PersistableBundle;
170import android.os.PowerManager;
171import android.os.PowerManagerInternal;
172import android.os.Process;
173import android.os.RemoteCallbackList;
174import android.os.RemoteException;
175import android.os.ResultReceiver;
176import android.os.ServiceManager;
177import android.os.StrictMode;
178import android.os.SystemClock;
179import android.os.SystemProperties;
180import android.os.Trace;
181import android.os.TransactionTooLargeException;
182import android.os.UpdateLock;
183import android.os.UserHandle;
184import android.os.UserManager;
185import android.os.WorkSource;
186import android.os.storage.IMountService;
187import android.os.storage.MountServiceInternal;
188import android.os.storage.StorageManager;
189import android.provider.Settings;
190import android.service.voice.IVoiceInteractionSession;
191import android.service.voice.VoiceInteractionManagerInternal;
192import android.service.voice.VoiceInteractionSession;
193import android.text.format.DateUtils;
194import android.text.format.Time;
195import android.util.ArrayMap;
196import android.util.ArraySet;
197import android.util.AtomicFile;
198import android.util.DebugUtils;
199import android.util.EventLog;
200import android.util.LocaleList;
201import android.util.Log;
202import android.util.Pair;
203import android.util.PrintWriterPrinter;
204import android.util.Slog;
205import android.util.SparseArray;
206import android.util.TimeUtils;
207import android.util.Xml;
208import android.view.Display;
209import android.view.Gravity;
210import android.view.LayoutInflater;
211import android.view.View;
212import android.view.WindowManager;
213
214import java.io.BufferedInputStream;
215import java.io.BufferedOutputStream;
216import java.io.DataInputStream;
217import java.io.DataOutputStream;
218import java.io.File;
219import java.io.FileDescriptor;
220import java.io.FileInputStream;
221import java.io.FileNotFoundException;
222import java.io.FileOutputStream;
223import java.io.IOException;
224import java.io.InputStreamReader;
225import java.io.PrintWriter;
226import java.io.StringWriter;
227import java.lang.ref.WeakReference;
228import java.nio.charset.StandardCharsets;
229import java.util.ArrayList;
230import java.util.Arrays;
231import java.util.Collections;
232import java.util.Comparator;
233import java.util.HashMap;
234import java.util.HashSet;
235import java.util.Iterator;
236import java.util.List;
237import java.util.Locale;
238import java.util.Map;
239import java.util.Set;
240import java.util.concurrent.atomic.AtomicBoolean;
241import java.util.concurrent.atomic.AtomicLong;
242
243import dalvik.system.VMRuntime;
244
245import libcore.io.IoUtils;
246import libcore.util.EmptyArray;
247
248import static android.Manifest.permission.INTERACT_ACROSS_USERS;
249import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
250import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
251import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
252import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
253import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
254import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
255import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
256import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
257import static android.app.ActivityManager.StackId.HOME_STACK_ID;
258import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
259import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
260import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
261import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
262import static android.content.pm.PackageManager.GET_PROVIDERS;
263import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
264import static android.content.pm.PackageManager.MATCH_ENCRYPTION_UNAWARE;
265import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
266import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
267import static android.content.pm.PackageManager.PERMISSION_GRANTED;
268import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
269import static android.provider.Settings.Global.DEBUG_APP;
270import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
271import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
272import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
273import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
274import static android.provider.Settings.System.FONT_SCALE;
275import static com.android.internal.util.XmlUtils.readBooleanAttribute;
276import static com.android.internal.util.XmlUtils.readIntAttribute;
277import static com.android.internal.util.XmlUtils.readLongAttribute;
278import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
279import static com.android.internal.util.XmlUtils.writeIntAttribute;
280import static com.android.internal.util.XmlUtils.writeLongAttribute;
281import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
282import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
283import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
312import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
313import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
314import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
336import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
337import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
338import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
339import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
340import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
341import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
342import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
343import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
344import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
345import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
346import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
347import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
348import static org.xmlpull.v1.XmlPullParser.START_TAG;
349
350public final class ActivityManagerService extends ActivityManagerNative
351        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
352
353    // File that stores last updated system version and called preboot receivers
354    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
355
356    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
357    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
358    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
359    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
360    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
361    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
362    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
363    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
364    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
365    private static final String TAG_LRU = TAG + POSTFIX_LRU;
366    private static final String TAG_MU = TAG + POSTFIX_MU;
367    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
368    private static final String TAG_POWER = TAG + POSTFIX_POWER;
369    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
370    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
371    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
372    private static final String TAG_PSS = TAG + POSTFIX_PSS;
373    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
374    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
375    private static final String TAG_STACK = TAG + POSTFIX_STACK;
376    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
377    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
378    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
379    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
380    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
381
382    /** Control over CPU and battery monitoring */
383    // write battery stats every 30 minutes.
384    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
385    static final boolean MONITOR_CPU_USAGE = true;
386    // don't sample cpu less than every 5 seconds.
387    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
388    // wait possibly forever for next cpu sample.
389    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
390    static final boolean MONITOR_THREAD_CPU_USAGE = false;
391
392    // The flags that are set for all calls we make to the package manager.
393    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
394
395    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
396
397    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
398
399    // Amount of time after a call to stopAppSwitches() during which we will
400    // prevent further untrusted switches from happening.
401    static final long APP_SWITCH_DELAY_TIME = 5*1000;
402
403    // How long we wait for a launched process to attach to the activity manager
404    // before we decide it's never going to come up for real.
405    static final int PROC_START_TIMEOUT = 10*1000;
406    // How long we wait for an attached process to publish its content providers
407    // before we decide it must be hung.
408    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
409
410    // How long we will retain processes hosting content providers in the "last activity"
411    // state before allowing them to drop down to the regular cached LRU list.  This is
412    // to avoid thrashing of provider processes under low memory situations.
413    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
414
415    // How long we wait for a launched process to attach to the activity manager
416    // before we decide it's never going to come up for real, when the process was
417    // started with a wrapper for instrumentation (such as Valgrind) because it
418    // could take much longer than usual.
419    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
420
421    // How long to wait after going idle before forcing apps to GC.
422    static final int GC_TIMEOUT = 5*1000;
423
424    // The minimum amount of time between successive GC requests for a process.
425    static final int GC_MIN_INTERVAL = 60*1000;
426
427    // The minimum amount of time between successive PSS requests for a process.
428    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
429
430    // The minimum amount of time between successive PSS requests for a process
431    // when the request is due to the memory state being lowered.
432    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
433
434    // The rate at which we check for apps using excessive power -- 15 mins.
435    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
436
437    // The minimum sample duration we will allow before deciding we have
438    // enough data on wake locks to start killing things.
439    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
440
441    // The minimum sample duration we will allow before deciding we have
442    // enough data on CPU usage to start killing things.
443    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
444
445    // How long we allow a receiver to run before giving up on it.
446    static final int BROADCAST_FG_TIMEOUT = 10*1000;
447    static final int BROADCAST_BG_TIMEOUT = 60*1000;
448
449    // How long we wait until we timeout on key dispatching.
450    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
451
452    // How long we wait until we timeout on key dispatching during instrumentation.
453    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
454
455    // This is the amount of time an app needs to be running a foreground service before
456    // we will consider it to be doing interaction for usage stats.
457    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
458
459    // Maximum amount of time we will allow to elapse before re-reporting usage stats
460    // interaction with foreground processes.
461    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
462
463    // This is the amount of time we allow an app to settle after it goes into the background,
464    // before we start restricting what it can do.
465    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
466
467    // How long to wait in getAssistContextExtras for the activity and foreground services
468    // to respond with the result.
469    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
470
471    // How long top wait when going through the modern assist (which doesn't need to block
472    // on getting this result before starting to launch its UI).
473    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
474
475    // Maximum number of persisted Uri grants a package is allowed
476    static final int MAX_PERSISTED_URI_GRANTS = 128;
477
478    static final int MY_PID = Process.myPid();
479
480    static final String[] EMPTY_STRING_ARRAY = new String[0];
481
482    // How many bytes to write into the dropbox log before truncating
483    static final int DROPBOX_MAX_SIZE = 256 * 1024;
484
485    // Access modes for handleIncomingUser.
486    static final int ALLOW_NON_FULL = 0;
487    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
488    static final int ALLOW_FULL_ONLY = 2;
489
490    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
491
492    // Delay in notifying task stack change listeners (in millis)
493    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
494
495    // Necessary ApplicationInfo flags to mark an app as persistent
496    private static final int PERSISTENT_MASK =
497            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
498
499
500    // Delay to disable app launch boost
501    static final int APP_BOOST_MESSAGE_DELAY = 3000;
502    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
503    static final int APP_BOOST_TIMEOUT = 2500;
504
505    // Used to indicate that a task is removed it should also be removed from recents.
506    private static final boolean REMOVE_FROM_RECENTS = true;
507    // Used to indicate that an app transition should be animated.
508    static final boolean ANIMATE = true;
509
510    // Determines whether to take full screen screenshots
511    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
512
513    private static native int nativeMigrateToBoost();
514    private static native int nativeMigrateFromBoost();
515    private boolean mIsBoosted = false;
516    private long mBoostStartTime = 0;
517
518    /** All system services */
519    SystemServiceManager mSystemServiceManager;
520
521    private Installer mInstaller;
522
523    /** Run all ActivityStacks through this */
524    final ActivityStackSupervisor mStackSupervisor;
525
526    final ActivityStarter mActivityStarter;
527
528    /** Task stack change listeners. */
529    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
530            new RemoteCallbackList<ITaskStackListener>();
531
532    public IntentFirewall mIntentFirewall;
533
534    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
535    // default actuion automatically.  Important for devices without direct input
536    // devices.
537    private boolean mShowDialogs = true;
538    private boolean mInVrMode = false;
539
540    BroadcastQueue mFgBroadcastQueue;
541    BroadcastQueue mBgBroadcastQueue;
542    // Convenient for easy iteration over the queues. Foreground is first
543    // so that dispatch of foreground broadcasts gets precedence.
544    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
545
546    BroadcastQueue broadcastQueueForIntent(Intent intent) {
547        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
548        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
549                "Broadcast intent " + intent + " on "
550                + (isFg ? "foreground" : "background") + " queue");
551        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
552    }
553
554    /**
555     * Activity we have told the window manager to have key focus.
556     */
557    ActivityRecord mFocusedActivity = null;
558
559    /**
560     * User id of the last activity mFocusedActivity was set to.
561     */
562    private int mLastFocusedUserId;
563
564    /**
565     * If non-null, we are tracking the time the user spends in the currently focused app.
566     */
567    private AppTimeTracker mCurAppTimeTracker;
568
569    /**
570     * List of intents that were used to start the most recent tasks.
571     */
572    final RecentTasks mRecentTasks;
573
574    /**
575     * For addAppTask: cached of the last activity component that was added.
576     */
577    ComponentName mLastAddedTaskComponent;
578
579    /**
580     * For addAppTask: cached of the last activity uid that was added.
581     */
582    int mLastAddedTaskUid;
583
584    /**
585     * For addAppTask: cached of the last ActivityInfo that was added.
586     */
587    ActivityInfo mLastAddedTaskActivity;
588
589    /**
590     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
591     */
592    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
593
594    /**
595     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
596     */
597    String mDeviceOwnerName;
598
599    final UserController mUserController;
600
601    final AppErrors mAppErrors;
602
603    public boolean canShowErrorDialogs() {
604        return mShowDialogs && !mSleeping && !mShuttingDown;
605    }
606
607    public class PendingAssistExtras extends Binder implements Runnable {
608        public final ActivityRecord activity;
609        public final Bundle extras;
610        public final Intent intent;
611        public final String hint;
612        public final IResultReceiver receiver;
613        public final int userHandle;
614        public boolean haveResult = false;
615        public Bundle result = null;
616        public AssistStructure structure = null;
617        public AssistContent content = null;
618        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
619                String _hint, IResultReceiver _receiver, int _userHandle) {
620            activity = _activity;
621            extras = _extras;
622            intent = _intent;
623            hint = _hint;
624            receiver = _receiver;
625            userHandle = _userHandle;
626        }
627        @Override
628        public void run() {
629            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
630            synchronized (this) {
631                haveResult = true;
632                notifyAll();
633            }
634            pendingAssistExtrasTimedOut(this);
635        }
636    }
637
638    final ArrayList<PendingAssistExtras> mPendingAssistExtras
639            = new ArrayList<PendingAssistExtras>();
640
641    /**
642     * Process management.
643     */
644    final ProcessList mProcessList = new ProcessList();
645
646    /**
647     * All of the applications we currently have running organized by name.
648     * The keys are strings of the application package name (as
649     * returned by the package manager), and the keys are ApplicationRecord
650     * objects.
651     */
652    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
653
654    /**
655     * Tracking long-term execution of processes to look for abuse and other
656     * bad app behavior.
657     */
658    final ProcessStatsService mProcessStats;
659
660    /**
661     * The currently running isolated processes.
662     */
663    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
664
665    /**
666     * Counter for assigning isolated process uids, to avoid frequently reusing the
667     * same ones.
668     */
669    int mNextIsolatedProcessUid = 0;
670
671    /**
672     * The currently running heavy-weight process, if any.
673     */
674    ProcessRecord mHeavyWeightProcess = null;
675
676    /**
677     * All of the processes we currently have running organized by pid.
678     * The keys are the pid running the application.
679     *
680     * <p>NOTE: This object is protected by its own lock, NOT the global
681     * activity manager lock!
682     */
683    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
684
685    /**
686     * All of the processes that have been forced to be foreground.  The key
687     * is the pid of the caller who requested it (we hold a death
688     * link on it).
689     */
690    abstract class ForegroundToken implements IBinder.DeathRecipient {
691        int pid;
692        IBinder token;
693    }
694    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
695
696    /**
697     * List of records for processes that someone had tried to start before the
698     * system was ready.  We don't start them at that point, but ensure they
699     * are started by the time booting is complete.
700     */
701    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
702
703    /**
704     * List of persistent applications that are in the process
705     * of being started.
706     */
707    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
708
709    /**
710     * Processes that are being forcibly torn down.
711     */
712    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
713
714    /**
715     * List of running applications, sorted by recent usage.
716     * The first entry in the list is the least recently used.
717     */
718    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
719
720    /**
721     * Where in mLruProcesses that the processes hosting activities start.
722     */
723    int mLruProcessActivityStart = 0;
724
725    /**
726     * Where in mLruProcesses that the processes hosting services start.
727     * This is after (lower index) than mLruProcessesActivityStart.
728     */
729    int mLruProcessServiceStart = 0;
730
731    /**
732     * List of processes that should gc as soon as things are idle.
733     */
734    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
735
736    /**
737     * Processes we want to collect PSS data from.
738     */
739    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
740
741    private boolean mBinderTransactionTrackingEnabled = false;
742
743    /**
744     * Last time we requested PSS data of all processes.
745     */
746    long mLastFullPssTime = SystemClock.uptimeMillis();
747
748    /**
749     * If set, the next time we collect PSS data we should do a full collection
750     * with data from native processes and the kernel.
751     */
752    boolean mFullPssPending = false;
753
754    /**
755     * This is the process holding what we currently consider to be
756     * the "home" activity.
757     */
758    ProcessRecord mHomeProcess;
759
760    /**
761     * This is the process holding the activity the user last visited that
762     * is in a different process from the one they are currently in.
763     */
764    ProcessRecord mPreviousProcess;
765
766    /**
767     * The time at which the previous process was last visible.
768     */
769    long mPreviousProcessVisibleTime;
770
771    /**
772     * Track all uids that have actively running processes.
773     */
774    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
775
776    /**
777     * This is for verifying the UID report flow.
778     */
779    static final boolean VALIDATE_UID_STATES = true;
780    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
781
782    /**
783     * Packages that the user has asked to have run in screen size
784     * compatibility mode instead of filling the screen.
785     */
786    final CompatModePackages mCompatModePackages;
787
788    /**
789     * Set of IntentSenderRecord objects that are currently active.
790     */
791    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
792            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
793
794    /**
795     * Fingerprints (hashCode()) of stack traces that we've
796     * already logged DropBox entries for.  Guarded by itself.  If
797     * something (rogue user app) forces this over
798     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
799     */
800    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
801    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
802
803    /**
804     * Strict Mode background batched logging state.
805     *
806     * The string buffer is guarded by itself, and its lock is also
807     * used to determine if another batched write is already
808     * in-flight.
809     */
810    private final StringBuilder mStrictModeBuffer = new StringBuilder();
811
812    /**
813     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
814     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
815     */
816    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
817
818    /**
819     * Resolver for broadcast intents to registered receivers.
820     * Holds BroadcastFilter (subclass of IntentFilter).
821     */
822    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
823            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
824        @Override
825        protected boolean allowFilterResult(
826                BroadcastFilter filter, List<BroadcastFilter> dest) {
827            IBinder target = filter.receiverList.receiver.asBinder();
828            for (int i = dest.size() - 1; i >= 0; i--) {
829                if (dest.get(i).receiverList.receiver.asBinder() == target) {
830                    return false;
831                }
832            }
833            return true;
834        }
835
836        @Override
837        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
838            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
839                    || userId == filter.owningUserId) {
840                return super.newResult(filter, match, userId);
841            }
842            return null;
843        }
844
845        @Override
846        protected BroadcastFilter[] newArray(int size) {
847            return new BroadcastFilter[size];
848        }
849
850        @Override
851        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
852            return packageName.equals(filter.packageName);
853        }
854    };
855
856    /**
857     * State of all active sticky broadcasts per user.  Keys are the action of the
858     * sticky Intent, values are an ArrayList of all broadcasted intents with
859     * that action (which should usually be one).  The SparseArray is keyed
860     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
861     * for stickies that are sent to all users.
862     */
863    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
864            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
865
866    final ActiveServices mServices;
867
868    final static class Association {
869        final int mSourceUid;
870        final String mSourceProcess;
871        final int mTargetUid;
872        final ComponentName mTargetComponent;
873        final String mTargetProcess;
874
875        int mCount;
876        long mTime;
877
878        int mNesting;
879        long mStartTime;
880
881        Association(int sourceUid, String sourceProcess, int targetUid,
882                ComponentName targetComponent, String targetProcess) {
883            mSourceUid = sourceUid;
884            mSourceProcess = sourceProcess;
885            mTargetUid = targetUid;
886            mTargetComponent = targetComponent;
887            mTargetProcess = targetProcess;
888        }
889    }
890
891    /**
892     * When service association tracking is enabled, this is all of the associations we
893     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
894     * -> association data.
895     */
896    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
897            mAssociations = new SparseArray<>();
898    boolean mTrackingAssociations;
899
900    /**
901     * Backup/restore process management
902     */
903    String mBackupAppName = null;
904    BackupRecord mBackupTarget = null;
905
906    final ProviderMap mProviderMap;
907
908    /**
909     * List of content providers who have clients waiting for them.  The
910     * application is currently being launched and the provider will be
911     * removed from this list once it is published.
912     */
913    final ArrayList<ContentProviderRecord> mLaunchingProviders
914            = new ArrayList<ContentProviderRecord>();
915
916    /**
917     * File storing persisted {@link #mGrantedUriPermissions}.
918     */
919    private final AtomicFile mGrantFile;
920
921    /** XML constants used in {@link #mGrantFile} */
922    private static final String TAG_URI_GRANTS = "uri-grants";
923    private static final String TAG_URI_GRANT = "uri-grant";
924    private static final String ATTR_USER_HANDLE = "userHandle";
925    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
926    private static final String ATTR_TARGET_USER_ID = "targetUserId";
927    private static final String ATTR_SOURCE_PKG = "sourcePkg";
928    private static final String ATTR_TARGET_PKG = "targetPkg";
929    private static final String ATTR_URI = "uri";
930    private static final String ATTR_MODE_FLAGS = "modeFlags";
931    private static final String ATTR_CREATED_TIME = "createdTime";
932    private static final String ATTR_PREFIX = "prefix";
933
934    /**
935     * Global set of specific {@link Uri} permissions that have been granted.
936     * This optimized lookup structure maps from {@link UriPermission#targetUid}
937     * to {@link UriPermission#uri} to {@link UriPermission}.
938     */
939    @GuardedBy("this")
940    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
941            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
942
943    public static class GrantUri {
944        public final int sourceUserId;
945        public final Uri uri;
946        public boolean prefix;
947
948        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
949            this.sourceUserId = sourceUserId;
950            this.uri = uri;
951            this.prefix = prefix;
952        }
953
954        @Override
955        public int hashCode() {
956            int hashCode = 1;
957            hashCode = 31 * hashCode + sourceUserId;
958            hashCode = 31 * hashCode + uri.hashCode();
959            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
960            return hashCode;
961        }
962
963        @Override
964        public boolean equals(Object o) {
965            if (o instanceof GrantUri) {
966                GrantUri other = (GrantUri) o;
967                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
968                        && prefix == other.prefix;
969            }
970            return false;
971        }
972
973        @Override
974        public String toString() {
975            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
976            if (prefix) result += " [prefix]";
977            return result;
978        }
979
980        public String toSafeString() {
981            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
982            if (prefix) result += " [prefix]";
983            return result;
984        }
985
986        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
987            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
988                    ContentProvider.getUriWithoutUserId(uri), false);
989        }
990    }
991
992    CoreSettingsObserver mCoreSettingsObserver;
993
994    FontScaleSettingObserver mFontScaleSettingObserver;
995
996    private final class FontScaleSettingObserver extends ContentObserver {
997        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
998
999        public FontScaleSettingObserver() {
1000            super(mHandler);
1001            ContentResolver resolver = mContext.getContentResolver();
1002            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1003        }
1004
1005        @Override
1006        public void onChange(boolean selfChange, Uri uri) {
1007            if (mFontScaleUri.equals(uri)) {
1008                updateFontScaleIfNeeded();
1009            }
1010        }
1011    }
1012
1013    /**
1014     * Thread-local storage used to carry caller permissions over through
1015     * indirect content-provider access.
1016     */
1017    private class Identity {
1018        public final IBinder token;
1019        public final int pid;
1020        public final int uid;
1021
1022        Identity(IBinder _token, int _pid, int _uid) {
1023            token = _token;
1024            pid = _pid;
1025            uid = _uid;
1026        }
1027    }
1028
1029    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1030
1031    /**
1032     * All information we have collected about the runtime performance of
1033     * any user id that can impact battery performance.
1034     */
1035    final BatteryStatsService mBatteryStatsService;
1036
1037    /**
1038     * Information about component usage
1039     */
1040    UsageStatsManagerInternal mUsageStatsService;
1041
1042    /**
1043     * Access to DeviceIdleController service.
1044     */
1045    DeviceIdleController.LocalService mLocalDeviceIdleController;
1046
1047    /**
1048     * Information about and control over application operations
1049     */
1050    final AppOpsService mAppOpsService;
1051
1052    /**
1053     * Current configuration information.  HistoryRecord objects are given
1054     * a reference to this object to indicate which configuration they are
1055     * currently running in, so this object must be kept immutable.
1056     */
1057    Configuration mConfiguration = new Configuration();
1058
1059    /**
1060     * Current sequencing integer of the configuration, for skipping old
1061     * configurations.
1062     */
1063    int mConfigurationSeq = 0;
1064
1065    boolean mSuppressResizeConfigChanges = false;
1066
1067    /**
1068     * Hardware-reported OpenGLES version.
1069     */
1070    final int GL_ES_VERSION;
1071
1072    /**
1073     * List of initialization arguments to pass to all processes when binding applications to them.
1074     * For example, references to the commonly used services.
1075     */
1076    HashMap<String, IBinder> mAppBindArgs;
1077
1078    /**
1079     * Temporary to avoid allocations.  Protected by main lock.
1080     */
1081    final StringBuilder mStringBuilder = new StringBuilder(256);
1082
1083    /**
1084     * Used to control how we initialize the service.
1085     */
1086    ComponentName mTopComponent;
1087    String mTopAction = Intent.ACTION_MAIN;
1088    String mTopData;
1089    boolean mProcessesReady = false;
1090    boolean mSystemReady = false;
1091    boolean mBooting = false;
1092    boolean mCallFinishBooting = false;
1093    boolean mBootAnimationComplete = false;
1094    boolean mWaitingUpdate = false;
1095    boolean mDidUpdate = false;
1096    boolean mOnBattery = false;
1097    boolean mLaunchWarningShown = false;
1098
1099    Context mContext;
1100
1101    int mFactoryTest;
1102
1103    boolean mCheckedForSetup;
1104
1105    /**
1106     * The time at which we will allow normal application switches again,
1107     * after a call to {@link #stopAppSwitches()}.
1108     */
1109    long mAppSwitchesAllowedTime;
1110
1111    /**
1112     * This is set to true after the first switch after mAppSwitchesAllowedTime
1113     * is set; any switches after that will clear the time.
1114     */
1115    boolean mDidAppSwitch;
1116
1117    /**
1118     * Last time (in realtime) at which we checked for power usage.
1119     */
1120    long mLastPowerCheckRealtime;
1121
1122    /**
1123     * Last time (in uptime) at which we checked for power usage.
1124     */
1125    long mLastPowerCheckUptime;
1126
1127    /**
1128     * Set while we are wanting to sleep, to prevent any
1129     * activities from being started/resumed.
1130     */
1131    private boolean mSleeping = false;
1132
1133    /**
1134     * The process state used for processes that are running the top activities.
1135     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1136     */
1137    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1138
1139    /**
1140     * Set while we are running a voice interaction.  This overrides
1141     * sleeping while it is active.
1142     */
1143    private IVoiceInteractionSession mRunningVoice;
1144
1145    /**
1146     * For some direct access we need to power manager.
1147     */
1148    PowerManagerInternal mLocalPowerManager;
1149
1150    /**
1151     * We want to hold a wake lock while running a voice interaction session, since
1152     * this may happen with the screen off and we need to keep the CPU running to
1153     * be able to continue to interact with the user.
1154     */
1155    PowerManager.WakeLock mVoiceWakeLock;
1156
1157    /**
1158     * State of external calls telling us if the device is awake or asleep.
1159     */
1160    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1161
1162    /**
1163     * A list of tokens that cause the top activity to be put to sleep.
1164     * They are used by components that may hide and block interaction with underlying
1165     * activities.
1166     */
1167    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1168
1169    static final int LOCK_SCREEN_HIDDEN = 0;
1170    static final int LOCK_SCREEN_LEAVING = 1;
1171    static final int LOCK_SCREEN_SHOWN = 2;
1172    /**
1173     * State of external call telling us if the lock screen is shown.
1174     */
1175    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1176
1177    /**
1178     * Set if we are shutting down the system, similar to sleeping.
1179     */
1180    boolean mShuttingDown = false;
1181
1182    /**
1183     * Current sequence id for oom_adj computation traversal.
1184     */
1185    int mAdjSeq = 0;
1186
1187    /**
1188     * Current sequence id for process LRU updating.
1189     */
1190    int mLruSeq = 0;
1191
1192    /**
1193     * Keep track of the non-cached/empty process we last found, to help
1194     * determine how to distribute cached/empty processes next time.
1195     */
1196    int mNumNonCachedProcs = 0;
1197
1198    /**
1199     * Keep track of the number of cached hidden procs, to balance oom adj
1200     * distribution between those and empty procs.
1201     */
1202    int mNumCachedHiddenProcs = 0;
1203
1204    /**
1205     * Keep track of the number of service processes we last found, to
1206     * determine on the next iteration which should be B services.
1207     */
1208    int mNumServiceProcs = 0;
1209    int mNewNumAServiceProcs = 0;
1210    int mNewNumServiceProcs = 0;
1211
1212    /**
1213     * Allow the current computed overall memory level of the system to go down?
1214     * This is set to false when we are killing processes for reasons other than
1215     * memory management, so that the now smaller process list will not be taken as
1216     * an indication that memory is tighter.
1217     */
1218    boolean mAllowLowerMemLevel = false;
1219
1220    /**
1221     * The last computed memory level, for holding when we are in a state that
1222     * processes are going away for other reasons.
1223     */
1224    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1225
1226    /**
1227     * The last total number of process we have, to determine if changes actually look
1228     * like a shrinking number of process due to lower RAM.
1229     */
1230    int mLastNumProcesses;
1231
1232    /**
1233     * The uptime of the last time we performed idle maintenance.
1234     */
1235    long mLastIdleTime = SystemClock.uptimeMillis();
1236
1237    /**
1238     * Total time spent with RAM that has been added in the past since the last idle time.
1239     */
1240    long mLowRamTimeSinceLastIdle = 0;
1241
1242    /**
1243     * If RAM is currently low, when that horrible situation started.
1244     */
1245    long mLowRamStartTime = 0;
1246
1247    /**
1248     * For reporting to battery stats the current top application.
1249     */
1250    private String mCurResumedPackage = null;
1251    private int mCurResumedUid = -1;
1252
1253    /**
1254     * For reporting to battery stats the apps currently running foreground
1255     * service.  The ProcessMap is package/uid tuples; each of these contain
1256     * an array of the currently foreground processes.
1257     */
1258    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1259            = new ProcessMap<ArrayList<ProcessRecord>>();
1260
1261    /**
1262     * This is set if we had to do a delayed dexopt of an app before launching
1263     * it, to increase the ANR timeouts in that case.
1264     */
1265    boolean mDidDexOpt;
1266
1267    /**
1268     * Set if the systemServer made a call to enterSafeMode.
1269     */
1270    boolean mSafeMode;
1271
1272    /**
1273     * If true, we are running under a test environment so will sample PSS from processes
1274     * much more rapidly to try to collect better data when the tests are rapidly
1275     * running through apps.
1276     */
1277    boolean mTestPssMode = false;
1278
1279    String mDebugApp = null;
1280    boolean mWaitForDebugger = false;
1281    boolean mDebugTransient = false;
1282    String mOrigDebugApp = null;
1283    boolean mOrigWaitForDebugger = false;
1284    boolean mAlwaysFinishActivities = false;
1285    boolean mForceResizableActivities;
1286    boolean mSupportsFreeformWindowManagement;
1287    boolean mSupportsPictureInPicture;
1288    Rect mDefaultPinnedStackBounds;
1289    IActivityController mController = null;
1290    String mProfileApp = null;
1291    ProcessRecord mProfileProc = null;
1292    String mProfileFile;
1293    ParcelFileDescriptor mProfileFd;
1294    int mSamplingInterval = 0;
1295    boolean mAutoStopProfiler = false;
1296    int mProfileType = 0;
1297    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1298    String mMemWatchDumpProcName;
1299    String mMemWatchDumpFile;
1300    int mMemWatchDumpPid;
1301    int mMemWatchDumpUid;
1302    String mTrackAllocationApp = null;
1303
1304    final long[] mTmpLong = new long[2];
1305
1306    static final class ProcessChangeItem {
1307        static final int CHANGE_ACTIVITIES = 1<<0;
1308        static final int CHANGE_PROCESS_STATE = 1<<1;
1309        int changes;
1310        int uid;
1311        int pid;
1312        int processState;
1313        boolean foregroundActivities;
1314    }
1315
1316    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1317    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1318
1319    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1320    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1321
1322    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1323    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1324
1325    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1326    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1327
1328    /**
1329     * Runtime CPU use collection thread.  This object's lock is used to
1330     * perform synchronization with the thread (notifying it to run).
1331     */
1332    final Thread mProcessCpuThread;
1333
1334    /**
1335     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1336     * Must acquire this object's lock when accessing it.
1337     * NOTE: this lock will be held while doing long operations (trawling
1338     * through all processes in /proc), so it should never be acquired by
1339     * any critical paths such as when holding the main activity manager lock.
1340     */
1341    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1342            MONITOR_THREAD_CPU_USAGE);
1343    final AtomicLong mLastCpuTime = new AtomicLong(0);
1344    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1345
1346    long mLastWriteTime = 0;
1347
1348    /**
1349     * Used to retain an update lock when the foreground activity is in
1350     * immersive mode.
1351     */
1352    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1353
1354    /**
1355     * Set to true after the system has finished booting.
1356     */
1357    boolean mBooted = false;
1358
1359    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1360    int mProcessLimitOverride = -1;
1361
1362    WindowManagerService mWindowManager;
1363
1364    final ActivityThread mSystemThread;
1365
1366    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1367        final ProcessRecord mApp;
1368        final int mPid;
1369        final IApplicationThread mAppThread;
1370
1371        AppDeathRecipient(ProcessRecord app, int pid,
1372                IApplicationThread thread) {
1373            if (DEBUG_ALL) Slog.v(
1374                TAG, "New death recipient " + this
1375                + " for thread " + thread.asBinder());
1376            mApp = app;
1377            mPid = pid;
1378            mAppThread = thread;
1379        }
1380
1381        @Override
1382        public void binderDied() {
1383            if (DEBUG_ALL) Slog.v(
1384                TAG, "Death received in " + this
1385                + " for thread " + mAppThread.asBinder());
1386            synchronized(ActivityManagerService.this) {
1387                appDiedLocked(mApp, mPid, mAppThread, true);
1388            }
1389        }
1390    }
1391
1392    static final int SHOW_ERROR_UI_MSG = 1;
1393    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1394    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1395    static final int UPDATE_CONFIGURATION_MSG = 4;
1396    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1397    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1398    static final int SERVICE_TIMEOUT_MSG = 12;
1399    static final int UPDATE_TIME_ZONE = 13;
1400    static final int SHOW_UID_ERROR_UI_MSG = 14;
1401    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1402    static final int PROC_START_TIMEOUT_MSG = 20;
1403    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1404    static final int KILL_APPLICATION_MSG = 22;
1405    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1406    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1407    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1408    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1409    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1410    static final int CLEAR_DNS_CACHE_MSG = 28;
1411    static final int UPDATE_HTTP_PROXY_MSG = 29;
1412    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1413    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1414    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1415    static final int REPORT_MEM_USAGE_MSG = 33;
1416    static final int REPORT_USER_SWITCH_MSG = 34;
1417    static final int CONTINUE_USER_SWITCH_MSG = 35;
1418    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1419    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1420    static final int PERSIST_URI_GRANTS_MSG = 38;
1421    static final int REQUEST_ALL_PSS_MSG = 39;
1422    static final int START_PROFILES_MSG = 40;
1423    static final int UPDATE_TIME = 41;
1424    static final int SYSTEM_USER_START_MSG = 42;
1425    static final int SYSTEM_USER_CURRENT_MSG = 43;
1426    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1427    static final int FINISH_BOOTING_MSG = 45;
1428    static final int START_USER_SWITCH_UI_MSG = 46;
1429    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1430    static final int DISMISS_DIALOG_UI_MSG = 48;
1431    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1432    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1433    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1434    static final int DELETE_DUMPHEAP_MSG = 52;
1435    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1436    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1437    static final int REPORT_TIME_TRACKER_MSG = 55;
1438    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1439    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1440    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1441    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1442    static final int IDLE_UIDS_MSG = 60;
1443    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1444    static final int LOG_STACK_STATE = 62;
1445    static final int VR_MODE_CHANGE_MSG = 63;
1446    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1447    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1448
1449    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1450    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1451    static final int FIRST_COMPAT_MODE_MSG = 300;
1452    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1453
1454    CompatModeDialog mCompatModeDialog;
1455    long mLastMemUsageReportTime = 0;
1456
1457    /**
1458     * Flag whether the current user is a "monkey", i.e. whether
1459     * the UI is driven by a UI automation tool.
1460     */
1461    private boolean mUserIsMonkey;
1462
1463    /** Flag whether the device has a Recents UI */
1464    boolean mHasRecents;
1465
1466    /** The dimensions of the thumbnails in the Recents UI. */
1467    int mThumbnailWidth;
1468    int mThumbnailHeight;
1469
1470    final ServiceThread mHandlerThread;
1471    final MainHandler mHandler;
1472    final UiHandler mUiHandler;
1473    final ProcessStartLogger mProcessStartLogger;
1474
1475    PackageManagerInternal mPackageManagerInt;
1476
1477    final class UiHandler extends Handler {
1478        public UiHandler() {
1479            super(com.android.server.UiThread.get().getLooper(), null, true);
1480        }
1481
1482        @Override
1483        public void handleMessage(Message msg) {
1484            switch (msg.what) {
1485            case SHOW_ERROR_UI_MSG: {
1486                mAppErrors.handleShowAppErrorUi(msg);
1487                ensureBootCompleted();
1488            } break;
1489            case SHOW_NOT_RESPONDING_UI_MSG: {
1490                mAppErrors.handleShowAnrUi(msg);
1491                ensureBootCompleted();
1492            } break;
1493            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1494                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1495                synchronized (ActivityManagerService.this) {
1496                    ProcessRecord proc = (ProcessRecord) data.get("app");
1497                    if (proc == null) {
1498                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1499                        break;
1500                    }
1501                    if (proc.crashDialog != null) {
1502                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1503                        return;
1504                    }
1505                    AppErrorResult res = (AppErrorResult) data.get("result");
1506                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1507                        Dialog d = new StrictModeViolationDialog(mContext,
1508                                ActivityManagerService.this, res, proc);
1509                        d.show();
1510                        proc.crashDialog = d;
1511                    } else {
1512                        // The device is asleep, so just pretend that the user
1513                        // saw a crash dialog and hit "force quit".
1514                        res.set(0);
1515                    }
1516                }
1517                ensureBootCompleted();
1518            } break;
1519            case SHOW_FACTORY_ERROR_UI_MSG: {
1520                Dialog d = new FactoryErrorDialog(
1521                    mContext, msg.getData().getCharSequence("msg"));
1522                d.show();
1523                ensureBootCompleted();
1524            } break;
1525            case WAIT_FOR_DEBUGGER_UI_MSG: {
1526                synchronized (ActivityManagerService.this) {
1527                    ProcessRecord app = (ProcessRecord)msg.obj;
1528                    if (msg.arg1 != 0) {
1529                        if (!app.waitedForDebugger) {
1530                            Dialog d = new AppWaitingForDebuggerDialog(
1531                                    ActivityManagerService.this,
1532                                    mContext, app);
1533                            app.waitDialog = d;
1534                            app.waitedForDebugger = true;
1535                            d.show();
1536                        }
1537                    } else {
1538                        if (app.waitDialog != null) {
1539                            app.waitDialog.dismiss();
1540                            app.waitDialog = null;
1541                        }
1542                    }
1543                }
1544            } break;
1545            case SHOW_UID_ERROR_UI_MSG: {
1546                if (mShowDialogs) {
1547                    AlertDialog d = new BaseErrorDialog(mContext);
1548                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1549                    d.setCancelable(false);
1550                    d.setTitle(mContext.getText(R.string.android_system_label));
1551                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1552                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1553                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1554                    d.show();
1555                }
1556            } break;
1557            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1558                if (mShowDialogs) {
1559                    AlertDialog d = new BaseErrorDialog(mContext);
1560                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1561                    d.setCancelable(false);
1562                    d.setTitle(mContext.getText(R.string.android_system_label));
1563                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1564                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1565                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1566                    d.show();
1567                }
1568            } break;
1569            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1570                synchronized (ActivityManagerService.this) {
1571                    ActivityRecord ar = (ActivityRecord) msg.obj;
1572                    if (mCompatModeDialog != null) {
1573                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1574                                ar.info.applicationInfo.packageName)) {
1575                            return;
1576                        }
1577                        mCompatModeDialog.dismiss();
1578                        mCompatModeDialog = null;
1579                    }
1580                    if (ar != null && false) {
1581                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1582                                ar.packageName)) {
1583                            int mode = mCompatModePackages.computeCompatModeLocked(
1584                                    ar.info.applicationInfo);
1585                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1586                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1587                                mCompatModeDialog = new CompatModeDialog(
1588                                        ActivityManagerService.this, mContext,
1589                                        ar.info.applicationInfo);
1590                                mCompatModeDialog.show();
1591                            }
1592                        }
1593                    }
1594                }
1595                break;
1596            }
1597            case START_USER_SWITCH_UI_MSG: {
1598                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1599                break;
1600            }
1601            case DISMISS_DIALOG_UI_MSG: {
1602                final Dialog d = (Dialog) msg.obj;
1603                d.dismiss();
1604                break;
1605            }
1606            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1607                dispatchProcessesChanged();
1608                break;
1609            }
1610            case DISPATCH_PROCESS_DIED_UI_MSG: {
1611                final int pid = msg.arg1;
1612                final int uid = msg.arg2;
1613                dispatchProcessDied(pid, uid);
1614                break;
1615            }
1616            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1617                dispatchUidsChanged();
1618            } break;
1619            }
1620        }
1621    }
1622
1623    final class MainHandler extends Handler {
1624        public MainHandler(Looper looper) {
1625            super(looper, null, true);
1626        }
1627
1628        @Override
1629        public void handleMessage(Message msg) {
1630            switch (msg.what) {
1631            case UPDATE_CONFIGURATION_MSG: {
1632                final ContentResolver resolver = mContext.getContentResolver();
1633                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1634                        msg.arg1);
1635            } break;
1636            case GC_BACKGROUND_PROCESSES_MSG: {
1637                synchronized (ActivityManagerService.this) {
1638                    performAppGcsIfAppropriateLocked();
1639                }
1640            } break;
1641            case SERVICE_TIMEOUT_MSG: {
1642                if (mDidDexOpt) {
1643                    mDidDexOpt = false;
1644                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1645                    nmsg.obj = msg.obj;
1646                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1647                    return;
1648                }
1649                mServices.serviceTimeout((ProcessRecord)msg.obj);
1650            } break;
1651            case UPDATE_TIME_ZONE: {
1652                synchronized (ActivityManagerService.this) {
1653                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1654                        ProcessRecord r = mLruProcesses.get(i);
1655                        if (r.thread != null) {
1656                            try {
1657                                r.thread.updateTimeZone();
1658                            } catch (RemoteException ex) {
1659                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1660                            }
1661                        }
1662                    }
1663                }
1664            } break;
1665            case CLEAR_DNS_CACHE_MSG: {
1666                synchronized (ActivityManagerService.this) {
1667                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1668                        ProcessRecord r = mLruProcesses.get(i);
1669                        if (r.thread != null) {
1670                            try {
1671                                r.thread.clearDnsCache();
1672                            } catch (RemoteException ex) {
1673                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1674                            }
1675                        }
1676                    }
1677                }
1678            } break;
1679            case UPDATE_HTTP_PROXY_MSG: {
1680                ProxyInfo proxy = (ProxyInfo)msg.obj;
1681                String host = "";
1682                String port = "";
1683                String exclList = "";
1684                Uri pacFileUrl = Uri.EMPTY;
1685                if (proxy != null) {
1686                    host = proxy.getHost();
1687                    port = Integer.toString(proxy.getPort());
1688                    exclList = proxy.getExclusionListAsString();
1689                    pacFileUrl = proxy.getPacFileUrl();
1690                }
1691                synchronized (ActivityManagerService.this) {
1692                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1693                        ProcessRecord r = mLruProcesses.get(i);
1694                        if (r.thread != null) {
1695                            try {
1696                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1697                            } catch (RemoteException ex) {
1698                                Slog.w(TAG, "Failed to update http proxy for: " +
1699                                        r.info.processName);
1700                            }
1701                        }
1702                    }
1703                }
1704            } break;
1705            case PROC_START_TIMEOUT_MSG: {
1706                if (mDidDexOpt) {
1707                    mDidDexOpt = false;
1708                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1709                    nmsg.obj = msg.obj;
1710                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1711                    return;
1712                }
1713                ProcessRecord app = (ProcessRecord)msg.obj;
1714                synchronized (ActivityManagerService.this) {
1715                    processStartTimedOutLocked(app);
1716                }
1717            } break;
1718            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1719                ProcessRecord app = (ProcessRecord)msg.obj;
1720                synchronized (ActivityManagerService.this) {
1721                    processContentProviderPublishTimedOutLocked(app);
1722                }
1723            } break;
1724            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1727                }
1728            } break;
1729            case KILL_APPLICATION_MSG: {
1730                synchronized (ActivityManagerService.this) {
1731                    int appid = msg.arg1;
1732                    boolean restart = (msg.arg2 == 1);
1733                    Bundle bundle = (Bundle)msg.obj;
1734                    String pkg = bundle.getString("pkg");
1735                    String reason = bundle.getString("reason");
1736                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1737                            false, UserHandle.USER_ALL, reason);
1738                }
1739            } break;
1740            case FINALIZE_PENDING_INTENT_MSG: {
1741                ((PendingIntentRecord)msg.obj).completeFinalize();
1742            } break;
1743            case POST_HEAVY_NOTIFICATION_MSG: {
1744                INotificationManager inm = NotificationManager.getService();
1745                if (inm == null) {
1746                    return;
1747                }
1748
1749                ActivityRecord root = (ActivityRecord)msg.obj;
1750                ProcessRecord process = root.app;
1751                if (process == null) {
1752                    return;
1753                }
1754
1755                try {
1756                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1757                    String text = mContext.getString(R.string.heavy_weight_notification,
1758                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1759                    Notification notification = new Notification.Builder(context)
1760                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1761                            .setWhen(0)
1762                            .setOngoing(true)
1763                            .setTicker(text)
1764                            .setColor(mContext.getColor(
1765                                    com.android.internal.R.color.system_notification_accent_color))
1766                            .setContentTitle(text)
1767                            .setContentText(
1768                                    mContext.getText(R.string.heavy_weight_notification_detail))
1769                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1770                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1771                                    new UserHandle(root.userId)))
1772                            .build();
1773                    try {
1774                        int[] outId = new int[1];
1775                        inm.enqueueNotificationWithTag("android", "android", null,
1776                                R.string.heavy_weight_notification,
1777                                notification, outId, root.userId);
1778                    } catch (RuntimeException e) {
1779                        Slog.w(ActivityManagerService.TAG,
1780                                "Error showing notification for heavy-weight app", e);
1781                    } catch (RemoteException e) {
1782                    }
1783                } catch (NameNotFoundException e) {
1784                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1785                }
1786            } break;
1787            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1788                INotificationManager inm = NotificationManager.getService();
1789                if (inm == null) {
1790                    return;
1791                }
1792                try {
1793                    inm.cancelNotificationWithTag("android", null,
1794                            R.string.heavy_weight_notification,  msg.arg1);
1795                } catch (RuntimeException e) {
1796                    Slog.w(ActivityManagerService.TAG,
1797                            "Error canceling notification for service", e);
1798                } catch (RemoteException e) {
1799                }
1800            } break;
1801            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1802                synchronized (ActivityManagerService.this) {
1803                    checkExcessivePowerUsageLocked(true);
1804                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1805                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1806                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1807                }
1808            } break;
1809            case REPORT_MEM_USAGE_MSG: {
1810                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1811                Thread thread = new Thread() {
1812                    @Override public void run() {
1813                        reportMemUsage(memInfos);
1814                    }
1815                };
1816                thread.start();
1817                break;
1818            }
1819            case REPORT_USER_SWITCH_MSG: {
1820                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1821                break;
1822            }
1823            case CONTINUE_USER_SWITCH_MSG: {
1824                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1825                break;
1826            }
1827            case USER_SWITCH_TIMEOUT_MSG: {
1828                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1829                break;
1830            }
1831            case IMMERSIVE_MODE_LOCK_MSG: {
1832                final boolean nextState = (msg.arg1 != 0);
1833                if (mUpdateLock.isHeld() != nextState) {
1834                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1835                            "Applying new update lock state '" + nextState
1836                            + "' for " + (ActivityRecord)msg.obj);
1837                    if (nextState) {
1838                        mUpdateLock.acquire();
1839                    } else {
1840                        mUpdateLock.release();
1841                    }
1842                }
1843                break;
1844            }
1845            case PERSIST_URI_GRANTS_MSG: {
1846                writeGrantedUriPermissions();
1847                break;
1848            }
1849            case REQUEST_ALL_PSS_MSG: {
1850                synchronized (ActivityManagerService.this) {
1851                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1852                }
1853                break;
1854            }
1855            case START_PROFILES_MSG: {
1856                synchronized (ActivityManagerService.this) {
1857                    mUserController.startProfilesLocked();
1858                }
1859                break;
1860            }
1861            case UPDATE_TIME: {
1862                synchronized (ActivityManagerService.this) {
1863                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1864                        ProcessRecord r = mLruProcesses.get(i);
1865                        if (r.thread != null) {
1866                            try {
1867                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1868                            } catch (RemoteException ex) {
1869                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1870                            }
1871                        }
1872                    }
1873                }
1874                break;
1875            }
1876            case SYSTEM_USER_START_MSG: {
1877                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1878                        Integer.toString(msg.arg1), msg.arg1);
1879                mSystemServiceManager.startUser(msg.arg1);
1880                break;
1881            }
1882            case SYSTEM_USER_UNLOCK_MSG: {
1883                final int userId = msg.arg1;
1884                mSystemServiceManager.unlockUser(userId);
1885                mRecentTasks.cleanupLocked(userId);
1886                installEncryptionUnawareProviders(userId);
1887                break;
1888            }
1889            case SYSTEM_USER_CURRENT_MSG: {
1890                mBatteryStatsService.noteEvent(
1891                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1892                        Integer.toString(msg.arg2), msg.arg2);
1893                mBatteryStatsService.noteEvent(
1894                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1895                        Integer.toString(msg.arg1), msg.arg1);
1896                mSystemServiceManager.switchUser(msg.arg1);
1897                break;
1898            }
1899            case ENTER_ANIMATION_COMPLETE_MSG: {
1900                synchronized (ActivityManagerService.this) {
1901                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1902                    if (r != null && r.app != null && r.app.thread != null) {
1903                        try {
1904                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1905                        } catch (RemoteException e) {
1906                        }
1907                    }
1908                }
1909                break;
1910            }
1911            case FINISH_BOOTING_MSG: {
1912                if (msg.arg1 != 0) {
1913                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1914                    finishBooting();
1915                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1916                }
1917                if (msg.arg2 != 0) {
1918                    enableScreenAfterBoot();
1919                }
1920                break;
1921            }
1922            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1923                try {
1924                    Locale l = (Locale) msg.obj;
1925                    IBinder service = ServiceManager.getService("mount");
1926                    IMountService mountService = IMountService.Stub.asInterface(service);
1927                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1928                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1929                } catch (RemoteException e) {
1930                    Log.e(TAG, "Error storing locale for decryption UI", e);
1931                }
1932                break;
1933            }
1934            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1935                synchronized (ActivityManagerService.this) {
1936                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1937                        try {
1938                            // Make a one-way callback to the listener
1939                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1940                        } catch (RemoteException e){
1941                            // Handled by the RemoteCallbackList
1942                        }
1943                    }
1944                    mTaskStackListeners.finishBroadcast();
1945                }
1946                break;
1947            }
1948            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
1949                synchronized (ActivityManagerService.this) {
1950                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1951                        try {
1952                            // Make a one-way callback to the listener
1953                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
1954                        } catch (RemoteException e){
1955                            // Handled by the RemoteCallbackList
1956                        }
1957                    }
1958                    mTaskStackListeners.finishBroadcast();
1959                }
1960                break;
1961            }
1962            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
1963                synchronized (ActivityManagerService.this) {
1964                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1965                        try {
1966                            // Make a one-way callback to the listener
1967                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
1968                        } catch (RemoteException e){
1969                            // Handled by the RemoteCallbackList
1970                        }
1971                    }
1972                    mTaskStackListeners.finishBroadcast();
1973                }
1974                break;
1975            }
1976            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1977                final int uid = msg.arg1;
1978                final byte[] firstPacket = (byte[]) msg.obj;
1979
1980                synchronized (mPidsSelfLocked) {
1981                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1982                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1983                        if (p.uid == uid) {
1984                            try {
1985                                p.thread.notifyCleartextNetwork(firstPacket);
1986                            } catch (RemoteException ignored) {
1987                            }
1988                        }
1989                    }
1990                }
1991                break;
1992            }
1993            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1994                final String procName;
1995                final int uid;
1996                final long memLimit;
1997                final String reportPackage;
1998                synchronized (ActivityManagerService.this) {
1999                    procName = mMemWatchDumpProcName;
2000                    uid = mMemWatchDumpUid;
2001                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2002                    if (val == null) {
2003                        val = mMemWatchProcesses.get(procName, 0);
2004                    }
2005                    if (val != null) {
2006                        memLimit = val.first;
2007                        reportPackage = val.second;
2008                    } else {
2009                        memLimit = 0;
2010                        reportPackage = null;
2011                    }
2012                }
2013                if (procName == null) {
2014                    return;
2015                }
2016
2017                if (DEBUG_PSS) Slog.d(TAG_PSS,
2018                        "Showing dump heap notification from " + procName + "/" + uid);
2019
2020                INotificationManager inm = NotificationManager.getService();
2021                if (inm == null) {
2022                    return;
2023                }
2024
2025                String text = mContext.getString(R.string.dump_heap_notification, procName);
2026
2027
2028                Intent deleteIntent = new Intent();
2029                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2030                Intent intent = new Intent();
2031                intent.setClassName("android", DumpHeapActivity.class.getName());
2032                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2033                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2034                if (reportPackage != null) {
2035                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2036                }
2037                int userId = UserHandle.getUserId(uid);
2038                Notification notification = new Notification.Builder(mContext)
2039                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2040                        .setWhen(0)
2041                        .setOngoing(true)
2042                        .setAutoCancel(true)
2043                        .setTicker(text)
2044                        .setColor(mContext.getColor(
2045                                com.android.internal.R.color.system_notification_accent_color))
2046                        .setContentTitle(text)
2047                        .setContentText(
2048                                mContext.getText(R.string.dump_heap_notification_detail))
2049                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2050                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2051                                new UserHandle(userId)))
2052                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2053                                deleteIntent, 0, UserHandle.SYSTEM))
2054                        .build();
2055
2056                try {
2057                    int[] outId = new int[1];
2058                    inm.enqueueNotificationWithTag("android", "android", null,
2059                            R.string.dump_heap_notification,
2060                            notification, outId, userId);
2061                } catch (RuntimeException e) {
2062                    Slog.w(ActivityManagerService.TAG,
2063                            "Error showing notification for dump heap", e);
2064                } catch (RemoteException e) {
2065                }
2066            } break;
2067            case DELETE_DUMPHEAP_MSG: {
2068                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2069                        DumpHeapActivity.JAVA_URI,
2070                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2071                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2072                        UserHandle.myUserId());
2073                synchronized (ActivityManagerService.this) {
2074                    mMemWatchDumpFile = null;
2075                    mMemWatchDumpProcName = null;
2076                    mMemWatchDumpPid = -1;
2077                    mMemWatchDumpUid = -1;
2078                }
2079            } break;
2080            case FOREGROUND_PROFILE_CHANGED_MSG: {
2081                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2082            } break;
2083            case REPORT_TIME_TRACKER_MSG: {
2084                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2085                tracker.deliverResult(mContext);
2086            } break;
2087            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2088                mUserController.dispatchUserSwitchComplete(msg.arg1);
2089            } break;
2090            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2091                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2092                try {
2093                    connection.shutdown();
2094                } catch (RemoteException e) {
2095                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2096                }
2097                // Only a UiAutomation can set this flag and now that
2098                // it is finished we make sure it is reset to its default.
2099                mUserIsMonkey = false;
2100            } break;
2101            case APP_BOOST_DEACTIVATE_MSG: {
2102                synchronized(ActivityManagerService.this) {
2103                    if (mIsBoosted) {
2104                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2105                            nativeMigrateFromBoost();
2106                            mIsBoosted = false;
2107                            mBoostStartTime = 0;
2108                        } else {
2109                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2110                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2111                        }
2112                    }
2113                }
2114            } break;
2115            case IDLE_UIDS_MSG: {
2116                idleUids();
2117            } break;
2118            case LOG_STACK_STATE: {
2119                synchronized (ActivityManagerService.this) {
2120                    mStackSupervisor.logStackState();
2121                }
2122            } break;
2123            case VR_MODE_CHANGE_MSG: {
2124                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2125                final boolean vrMode = msg.arg1 != 0;
2126                vrService.setVrMode(vrMode);
2127
2128                if (mInVrMode != vrMode) {
2129                    synchronized (ActivityManagerService.this) {
2130                        mInVrMode = vrMode;
2131                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2132                    }
2133                }
2134            } break;
2135            }
2136        }
2137    };
2138
2139    static final int COLLECT_PSS_BG_MSG = 1;
2140
2141    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2142        @Override
2143        public void handleMessage(Message msg) {
2144            switch (msg.what) {
2145            case COLLECT_PSS_BG_MSG: {
2146                long start = SystemClock.uptimeMillis();
2147                MemInfoReader memInfo = null;
2148                synchronized (ActivityManagerService.this) {
2149                    if (mFullPssPending) {
2150                        mFullPssPending = false;
2151                        memInfo = new MemInfoReader();
2152                    }
2153                }
2154                if (memInfo != null) {
2155                    updateCpuStatsNow();
2156                    long nativeTotalPss = 0;
2157                    synchronized (mProcessCpuTracker) {
2158                        final int N = mProcessCpuTracker.countStats();
2159                        for (int j=0; j<N; j++) {
2160                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2161                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2162                                // This is definitely an application process; skip it.
2163                                continue;
2164                            }
2165                            synchronized (mPidsSelfLocked) {
2166                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2167                                    // This is one of our own processes; skip it.
2168                                    continue;
2169                                }
2170                            }
2171                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2172                        }
2173                    }
2174                    memInfo.readMemInfo();
2175                    synchronized (ActivityManagerService.this) {
2176                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2177                                + (SystemClock.uptimeMillis()-start) + "ms");
2178                        final long cachedKb = memInfo.getCachedSizeKb();
2179                        final long freeKb = memInfo.getFreeSizeKb();
2180                        final long zramKb = memInfo.getZramTotalSizeKb();
2181                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2182                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2183                                kernelKb*1024, nativeTotalPss*1024);
2184                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2185                                nativeTotalPss);
2186                    }
2187                }
2188
2189                int num = 0;
2190                long[] tmp = new long[2];
2191                do {
2192                    ProcessRecord proc;
2193                    int procState;
2194                    int pid;
2195                    long lastPssTime;
2196                    synchronized (ActivityManagerService.this) {
2197                        if (mPendingPssProcesses.size() <= 0) {
2198                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2199                                    "Collected PSS of " + num + " processes in "
2200                                    + (SystemClock.uptimeMillis() - start) + "ms");
2201                            mPendingPssProcesses.clear();
2202                            return;
2203                        }
2204                        proc = mPendingPssProcesses.remove(0);
2205                        procState = proc.pssProcState;
2206                        lastPssTime = proc.lastPssTime;
2207                        if (proc.thread != null && procState == proc.setProcState
2208                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2209                                        < SystemClock.uptimeMillis()) {
2210                            pid = proc.pid;
2211                        } else {
2212                            proc = null;
2213                            pid = 0;
2214                        }
2215                    }
2216                    if (proc != null) {
2217                        long pss = Debug.getPss(pid, tmp, null);
2218                        synchronized (ActivityManagerService.this) {
2219                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2220                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2221                                num++;
2222                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2223                                        SystemClock.uptimeMillis());
2224                            }
2225                        }
2226                    }
2227                } while (true);
2228            }
2229            }
2230        }
2231    };
2232
2233    public void setSystemProcess() {
2234        try {
2235            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2236            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2237            ServiceManager.addService("meminfo", new MemBinder(this));
2238            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2239            ServiceManager.addService("dbinfo", new DbBinder(this));
2240            if (MONITOR_CPU_USAGE) {
2241                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2242            }
2243            ServiceManager.addService("permission", new PermissionController(this));
2244            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2245
2246            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2247                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2248            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2249
2250            synchronized (this) {
2251                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2252                app.persistent = true;
2253                app.pid = MY_PID;
2254                app.maxAdj = ProcessList.SYSTEM_ADJ;
2255                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2256                synchronized (mPidsSelfLocked) {
2257                    mPidsSelfLocked.put(app.pid, app);
2258                }
2259                updateLruProcessLocked(app, false, null);
2260                updateOomAdjLocked();
2261            }
2262        } catch (PackageManager.NameNotFoundException e) {
2263            throw new RuntimeException(
2264                    "Unable to find android system package", e);
2265        }
2266    }
2267
2268    public void setWindowManager(WindowManagerService wm) {
2269        mWindowManager = wm;
2270        mStackSupervisor.setWindowManager(wm);
2271        mActivityStarter.setWindowManager(wm);
2272    }
2273
2274    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2275        mUsageStatsService = usageStatsManager;
2276    }
2277
2278    public void startObservingNativeCrashes() {
2279        final NativeCrashListener ncl = new NativeCrashListener(this);
2280        ncl.start();
2281    }
2282
2283    public IAppOpsService getAppOpsService() {
2284        return mAppOpsService;
2285    }
2286
2287    static class MemBinder extends Binder {
2288        ActivityManagerService mActivityManagerService;
2289        MemBinder(ActivityManagerService activityManagerService) {
2290            mActivityManagerService = activityManagerService;
2291        }
2292
2293        @Override
2294        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2295            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2296                    != PackageManager.PERMISSION_GRANTED) {
2297                pw.println("Permission Denial: can't dump meminfo from from pid="
2298                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2299                        + " without permission " + android.Manifest.permission.DUMP);
2300                return;
2301            }
2302
2303            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2304        }
2305    }
2306
2307    static class GraphicsBinder extends Binder {
2308        ActivityManagerService mActivityManagerService;
2309        GraphicsBinder(ActivityManagerService activityManagerService) {
2310            mActivityManagerService = activityManagerService;
2311        }
2312
2313        @Override
2314        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2315            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2316                    != PackageManager.PERMISSION_GRANTED) {
2317                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2318                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2319                        + " without permission " + android.Manifest.permission.DUMP);
2320                return;
2321            }
2322
2323            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2324        }
2325    }
2326
2327    static class DbBinder extends Binder {
2328        ActivityManagerService mActivityManagerService;
2329        DbBinder(ActivityManagerService activityManagerService) {
2330            mActivityManagerService = activityManagerService;
2331        }
2332
2333        @Override
2334        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2335            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2336                    != PackageManager.PERMISSION_GRANTED) {
2337                pw.println("Permission Denial: can't dump dbinfo from from pid="
2338                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2339                        + " without permission " + android.Manifest.permission.DUMP);
2340                return;
2341            }
2342
2343            mActivityManagerService.dumpDbInfo(fd, pw, args);
2344        }
2345    }
2346
2347    static class CpuBinder extends Binder {
2348        ActivityManagerService mActivityManagerService;
2349        CpuBinder(ActivityManagerService activityManagerService) {
2350            mActivityManagerService = activityManagerService;
2351        }
2352
2353        @Override
2354        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2355            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2356                    != PackageManager.PERMISSION_GRANTED) {
2357                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2358                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2359                        + " without permission " + android.Manifest.permission.DUMP);
2360                return;
2361            }
2362
2363            synchronized (mActivityManagerService.mProcessCpuTracker) {
2364                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2365                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2366                        SystemClock.uptimeMillis()));
2367            }
2368        }
2369    }
2370
2371    public static final class Lifecycle extends SystemService {
2372        private final ActivityManagerService mService;
2373
2374        public Lifecycle(Context context) {
2375            super(context);
2376            mService = new ActivityManagerService(context);
2377        }
2378
2379        @Override
2380        public void onStart() {
2381            mService.start();
2382        }
2383
2384        public ActivityManagerService getService() {
2385            return mService;
2386        }
2387    }
2388
2389    // Note: This method is invoked on the main thread but may need to attach various
2390    // handlers to other threads.  So take care to be explicit about the looper.
2391    public ActivityManagerService(Context systemContext) {
2392        mContext = systemContext;
2393        mFactoryTest = FactoryTest.getMode();
2394        mSystemThread = ActivityThread.currentActivityThread();
2395
2396        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2397
2398        mHandlerThread = new ServiceThread(TAG,
2399                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2400        mHandlerThread.start();
2401        mHandler = new MainHandler(mHandlerThread.getLooper());
2402        mUiHandler = new UiHandler();
2403
2404        mProcessStartLogger = new ProcessStartLogger();
2405
2406        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2407                "foreground", BROADCAST_FG_TIMEOUT, false);
2408        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2409                "background", BROADCAST_BG_TIMEOUT, true);
2410        mBroadcastQueues[0] = mFgBroadcastQueue;
2411        mBroadcastQueues[1] = mBgBroadcastQueue;
2412
2413        mServices = new ActiveServices(this);
2414        mProviderMap = new ProviderMap(this);
2415        mAppErrors = new AppErrors(mContext, this);
2416
2417        // TODO: Move creation of battery stats service outside of activity manager service.
2418        File dataDir = Environment.getDataDirectory();
2419        File systemDir = new File(dataDir, "system");
2420        systemDir.mkdirs();
2421        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2422        mBatteryStatsService.getActiveStatistics().readLocked();
2423        mBatteryStatsService.scheduleWriteToDisk();
2424        mOnBattery = DEBUG_POWER ? true
2425                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2426        mBatteryStatsService.getActiveStatistics().setCallback(this);
2427
2428        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2429
2430        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2431        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2432                new IAppOpsCallback.Stub() {
2433                    @Override public void opChanged(int op, int uid, String packageName) {
2434                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2435                            if (mAppOpsService.checkOperation(op, uid, packageName)
2436                                    != AppOpsManager.MODE_ALLOWED) {
2437                                runInBackgroundDisabled(uid);
2438                            }
2439                        }
2440                    }
2441                });
2442
2443        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2444
2445        mUserController = new UserController(this);
2446
2447        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2448            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2449
2450        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2451
2452        mConfiguration.setToDefaults();
2453        mConfiguration.setLocales(LocaleList.getDefault());
2454
2455        mConfigurationSeq = mConfiguration.seq = 1;
2456        mProcessCpuTracker.init();
2457
2458        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2459        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2460        mStackSupervisor = new ActivityStackSupervisor(this);
2461        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2462        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2463
2464
2465        mProcessCpuThread = new Thread("CpuTracker") {
2466            @Override
2467            public void run() {
2468                while (true) {
2469                    try {
2470                        try {
2471                            synchronized(this) {
2472                                final long now = SystemClock.uptimeMillis();
2473                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2474                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2475                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2476                                //        + ", write delay=" + nextWriteDelay);
2477                                if (nextWriteDelay < nextCpuDelay) {
2478                                    nextCpuDelay = nextWriteDelay;
2479                                }
2480                                if (nextCpuDelay > 0) {
2481                                    mProcessCpuMutexFree.set(true);
2482                                    this.wait(nextCpuDelay);
2483                                }
2484                            }
2485                        } catch (InterruptedException e) {
2486                        }
2487                        updateCpuStatsNow();
2488                    } catch (Exception e) {
2489                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2490                    }
2491                }
2492            }
2493        };
2494
2495        Watchdog.getInstance().addMonitor(this);
2496        Watchdog.getInstance().addThread(mHandler);
2497    }
2498
2499    public void setSystemServiceManager(SystemServiceManager mgr) {
2500        mSystemServiceManager = mgr;
2501    }
2502
2503    public void setInstaller(Installer installer) {
2504        mInstaller = installer;
2505    }
2506
2507    private void start() {
2508        Process.removeAllProcessGroups();
2509        mProcessCpuThread.start();
2510
2511        mBatteryStatsService.publish(mContext);
2512        mAppOpsService.publish(mContext);
2513        Slog.d("AppOps", "AppOpsService published");
2514        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2515    }
2516
2517    void onUserStoppedLocked(int userId) {
2518        mRecentTasks.unloadUserRecentsLocked(userId);
2519    }
2520
2521    public void initPowerManagement() {
2522        mStackSupervisor.initPowerManagement();
2523        mBatteryStatsService.initPowerManagement();
2524        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2525        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2526        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2527        mVoiceWakeLock.setReferenceCounted(false);
2528    }
2529
2530    @Override
2531    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2532            throws RemoteException {
2533        if (code == SYSPROPS_TRANSACTION) {
2534            // We need to tell all apps about the system property change.
2535            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2536            synchronized(this) {
2537                final int NP = mProcessNames.getMap().size();
2538                for (int ip=0; ip<NP; ip++) {
2539                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2540                    final int NA = apps.size();
2541                    for (int ia=0; ia<NA; ia++) {
2542                        ProcessRecord app = apps.valueAt(ia);
2543                        if (app.thread != null) {
2544                            procs.add(app.thread.asBinder());
2545                        }
2546                    }
2547                }
2548            }
2549
2550            int N = procs.size();
2551            for (int i=0; i<N; i++) {
2552                Parcel data2 = Parcel.obtain();
2553                try {
2554                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2555                } catch (RemoteException e) {
2556                }
2557                data2.recycle();
2558            }
2559        }
2560        try {
2561            return super.onTransact(code, data, reply, flags);
2562        } catch (RuntimeException e) {
2563            // The activity manager only throws security exceptions, so let's
2564            // log all others.
2565            if (!(e instanceof SecurityException)) {
2566                Slog.wtf(TAG, "Activity Manager Crash", e);
2567            }
2568            throw e;
2569        }
2570    }
2571
2572    void updateCpuStats() {
2573        final long now = SystemClock.uptimeMillis();
2574        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2575            return;
2576        }
2577        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2578            synchronized (mProcessCpuThread) {
2579                mProcessCpuThread.notify();
2580            }
2581        }
2582    }
2583
2584    void updateCpuStatsNow() {
2585        synchronized (mProcessCpuTracker) {
2586            mProcessCpuMutexFree.set(false);
2587            final long now = SystemClock.uptimeMillis();
2588            boolean haveNewCpuStats = false;
2589
2590            if (MONITOR_CPU_USAGE &&
2591                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2592                mLastCpuTime.set(now);
2593                mProcessCpuTracker.update();
2594                if (mProcessCpuTracker.hasGoodLastStats()) {
2595                    haveNewCpuStats = true;
2596                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2597                    //Slog.i(TAG, "Total CPU usage: "
2598                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2599
2600                    // Slog the cpu usage if the property is set.
2601                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2602                        int user = mProcessCpuTracker.getLastUserTime();
2603                        int system = mProcessCpuTracker.getLastSystemTime();
2604                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2605                        int irq = mProcessCpuTracker.getLastIrqTime();
2606                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2607                        int idle = mProcessCpuTracker.getLastIdleTime();
2608
2609                        int total = user + system + iowait + irq + softIrq + idle;
2610                        if (total == 0) total = 1;
2611
2612                        EventLog.writeEvent(EventLogTags.CPU,
2613                                ((user+system+iowait+irq+softIrq) * 100) / total,
2614                                (user * 100) / total,
2615                                (system * 100) / total,
2616                                (iowait * 100) / total,
2617                                (irq * 100) / total,
2618                                (softIrq * 100) / total);
2619                    }
2620                }
2621            }
2622
2623            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2624            synchronized(bstats) {
2625                synchronized(mPidsSelfLocked) {
2626                    if (haveNewCpuStats) {
2627                        if (bstats.startAddingCpuLocked()) {
2628                            int totalUTime = 0;
2629                            int totalSTime = 0;
2630                            final int N = mProcessCpuTracker.countStats();
2631                            for (int i=0; i<N; i++) {
2632                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2633                                if (!st.working) {
2634                                    continue;
2635                                }
2636                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2637                                totalUTime += st.rel_utime;
2638                                totalSTime += st.rel_stime;
2639                                if (pr != null) {
2640                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2641                                    if (ps == null || !ps.isActive()) {
2642                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2643                                                pr.info.uid, pr.processName);
2644                                    }
2645                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2646                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2647                                } else {
2648                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2649                                    if (ps == null || !ps.isActive()) {
2650                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2651                                                bstats.mapUid(st.uid), st.name);
2652                                    }
2653                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2654                                }
2655                            }
2656                            final int userTime = mProcessCpuTracker.getLastUserTime();
2657                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2658                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2659                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2660                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2661                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2662                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2663                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2664                        }
2665                    }
2666                }
2667
2668                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2669                    mLastWriteTime = now;
2670                    mBatteryStatsService.scheduleWriteToDisk();
2671                }
2672            }
2673        }
2674    }
2675
2676    @Override
2677    public void batteryNeedsCpuUpdate() {
2678        updateCpuStatsNow();
2679    }
2680
2681    @Override
2682    public void batteryPowerChanged(boolean onBattery) {
2683        // When plugging in, update the CPU stats first before changing
2684        // the plug state.
2685        updateCpuStatsNow();
2686        synchronized (this) {
2687            synchronized(mPidsSelfLocked) {
2688                mOnBattery = DEBUG_POWER ? true : onBattery;
2689            }
2690        }
2691    }
2692
2693    @Override
2694    public void batterySendBroadcast(Intent intent) {
2695        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2696                AppOpsManager.OP_NONE, null, false, false,
2697                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2698    }
2699
2700    /**
2701     * Initialize the application bind args. These are passed to each
2702     * process when the bindApplication() IPC is sent to the process. They're
2703     * lazily setup to make sure the services are running when they're asked for.
2704     */
2705    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2706        if (mAppBindArgs == null) {
2707            mAppBindArgs = new HashMap<>();
2708
2709            // Isolated processes won't get this optimization, so that we don't
2710            // violate the rules about which services they have access to.
2711            if (!isolated) {
2712                // Setup the application init args
2713                mAppBindArgs.put("package", ServiceManager.getService("package"));
2714                mAppBindArgs.put("window", ServiceManager.getService("window"));
2715                mAppBindArgs.put(Context.ALARM_SERVICE,
2716                        ServiceManager.getService(Context.ALARM_SERVICE));
2717            }
2718        }
2719        return mAppBindArgs;
2720    }
2721
2722    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2723        if (r == null || mFocusedActivity == r) {
2724            return false;
2725        }
2726
2727        if (!r.isFocusable()) {
2728            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2729            return false;
2730        }
2731
2732        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2733        final ActivityRecord last = mFocusedActivity;
2734        mFocusedActivity = r;
2735        if (r.task.isApplicationTask()) {
2736            if (mCurAppTimeTracker != r.appTimeTracker) {
2737                // We are switching app tracking.  Complete the current one.
2738                if (mCurAppTimeTracker != null) {
2739                    mCurAppTimeTracker.stop();
2740                    mHandler.obtainMessage(
2741                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2742                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2743                    mCurAppTimeTracker = null;
2744                }
2745                if (r.appTimeTracker != null) {
2746                    mCurAppTimeTracker = r.appTimeTracker;
2747                    startTimeTrackingFocusedActivityLocked();
2748                }
2749            } else {
2750                startTimeTrackingFocusedActivityLocked();
2751            }
2752        } else {
2753            r.appTimeTracker = null;
2754        }
2755        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2756        // TODO: Probably not, because we don't want to resume voice on switching
2757        // back to this activity
2758        if (r.task.voiceInteractor != null) {
2759            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2760        } else {
2761            finishRunningVoiceLocked();
2762            IVoiceInteractionSession session;
2763            if (last != null && ((session = last.task.voiceSession) != null
2764                    || (session = last.voiceSession) != null)) {
2765                // We had been in a voice interaction session, but now focused has
2766                // move to something different.  Just finish the session, we can't
2767                // return to it and retain the proper state and synchronization with
2768                // the voice interaction service.
2769                finishVoiceTask(session);
2770            }
2771        }
2772        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2773            mWindowManager.setFocusedApp(r.appToken, true);
2774        }
2775        applyUpdateLockStateLocked(r);
2776        applyUpdateVrModeLocked(r);
2777        if (mFocusedActivity.userId != mLastFocusedUserId) {
2778            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2779            mHandler.obtainMessage(
2780                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2781            mLastFocusedUserId = mFocusedActivity.userId;
2782        }
2783
2784        EventLogTags.writeAmFocusedActivity(
2785                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2786                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2787                reason);
2788        return true;
2789    }
2790
2791    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2792        if (mFocusedActivity != goingAway) {
2793            return;
2794        }
2795
2796        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2797        if (focusedStack != null) {
2798            final ActivityRecord top = focusedStack.topActivity();
2799            if (top != null && top.userId != mLastFocusedUserId) {
2800                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2801                mHandler.sendMessage(
2802                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2803                mLastFocusedUserId = top.userId;
2804            }
2805        }
2806
2807        // Try to move focus to another activity if possible.
2808        if (setFocusedActivityLocked(
2809                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2810            return;
2811        }
2812
2813        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2814                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2815        mFocusedActivity = null;
2816        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2817    }
2818
2819    @Override
2820    public void setFocusedStack(int stackId) {
2821        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2822        synchronized (ActivityManagerService.this) {
2823            ActivityStack stack = mStackSupervisor.getStack(stackId);
2824            if (stack != null) {
2825                ActivityRecord r = stack.topRunningActivityLocked();
2826                if (r != null) {
2827                    setFocusedActivityLocked(r, "setFocusedStack");
2828                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2829                }
2830            }
2831        }
2832    }
2833
2834    @Override
2835    public void setFocusedTask(int taskId) {
2836        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2837        long callingId = Binder.clearCallingIdentity();
2838        try {
2839            synchronized (ActivityManagerService.this) {
2840                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2841                if (task != null) {
2842                    final ActivityRecord r = task.topRunningActivityLocked();
2843                    if (setFocusedActivityLocked(r, "setFocusedTask")) {
2844                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
2845                    }
2846                }
2847            }
2848        } finally {
2849            Binder.restoreCallingIdentity(callingId);
2850        }
2851    }
2852
2853    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2854    @Override
2855    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2856        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2857        synchronized (this) {
2858            if (listener != null) {
2859                mTaskStackListeners.register(listener);
2860            }
2861        }
2862    }
2863
2864    @Override
2865    public void notifyActivityDrawn(IBinder token) {
2866        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2867        synchronized (this) {
2868            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2869            if (r != null) {
2870                r.task.stack.notifyActivityDrawnLocked(r);
2871            }
2872        }
2873    }
2874
2875    final void applyUpdateLockStateLocked(ActivityRecord r) {
2876        // Modifications to the UpdateLock state are done on our handler, outside
2877        // the activity manager's locks.  The new state is determined based on the
2878        // state *now* of the relevant activity record.  The object is passed to
2879        // the handler solely for logging detail, not to be consulted/modified.
2880        final boolean nextState = r != null && r.immersive;
2881        mHandler.sendMessage(
2882                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2883    }
2884
2885    final void applyUpdateVrModeLocked(ActivityRecord r) {
2886        mHandler.sendMessage(
2887                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2888    }
2889
2890    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2891        Message msg = Message.obtain();
2892        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2893        msg.obj = r.task.askedCompatMode ? null : r;
2894        mUiHandler.sendMessage(msg);
2895    }
2896
2897    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2898            String what, Object obj, ProcessRecord srcApp) {
2899        app.lastActivityTime = now;
2900
2901        if (app.activities.size() > 0) {
2902            // Don't want to touch dependent processes that are hosting activities.
2903            return index;
2904        }
2905
2906        int lrui = mLruProcesses.lastIndexOf(app);
2907        if (lrui < 0) {
2908            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2909                    + what + " " + obj + " from " + srcApp);
2910            return index;
2911        }
2912
2913        if (lrui >= index) {
2914            // Don't want to cause this to move dependent processes *back* in the
2915            // list as if they were less frequently used.
2916            return index;
2917        }
2918
2919        if (lrui >= mLruProcessActivityStart) {
2920            // Don't want to touch dependent processes that are hosting activities.
2921            return index;
2922        }
2923
2924        mLruProcesses.remove(lrui);
2925        if (index > 0) {
2926            index--;
2927        }
2928        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2929                + " in LRU list: " + app);
2930        mLruProcesses.add(index, app);
2931        return index;
2932    }
2933
2934    static void killProcessGroup(int uid, int pid) {
2935        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2936        Process.killProcessGroup(uid, pid);
2937        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2938    }
2939
2940    final void removeLruProcessLocked(ProcessRecord app) {
2941        int lrui = mLruProcesses.lastIndexOf(app);
2942        if (lrui >= 0) {
2943            if (!app.killed) {
2944                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2945                Process.killProcessQuiet(app.pid);
2946                killProcessGroup(app.info.uid, app.pid);
2947            }
2948            if (lrui <= mLruProcessActivityStart) {
2949                mLruProcessActivityStart--;
2950            }
2951            if (lrui <= mLruProcessServiceStart) {
2952                mLruProcessServiceStart--;
2953            }
2954            mLruProcesses.remove(lrui);
2955        }
2956    }
2957
2958    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2959            ProcessRecord client) {
2960        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2961                || app.treatLikeActivity;
2962        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2963        if (!activityChange && hasActivity) {
2964            // The process has activities, so we are only allowing activity-based adjustments
2965            // to move it.  It should be kept in the front of the list with other
2966            // processes that have activities, and we don't want those to change their
2967            // order except due to activity operations.
2968            return;
2969        }
2970
2971        mLruSeq++;
2972        final long now = SystemClock.uptimeMillis();
2973        app.lastActivityTime = now;
2974
2975        // First a quick reject: if the app is already at the position we will
2976        // put it, then there is nothing to do.
2977        if (hasActivity) {
2978            final int N = mLruProcesses.size();
2979            if (N > 0 && mLruProcesses.get(N-1) == app) {
2980                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2981                return;
2982            }
2983        } else {
2984            if (mLruProcessServiceStart > 0
2985                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2986                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2987                return;
2988            }
2989        }
2990
2991        int lrui = mLruProcesses.lastIndexOf(app);
2992
2993        if (app.persistent && lrui >= 0) {
2994            // We don't care about the position of persistent processes, as long as
2995            // they are in the list.
2996            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2997            return;
2998        }
2999
3000        /* In progress: compute new position first, so we can avoid doing work
3001           if the process is not actually going to move.  Not yet working.
3002        int addIndex;
3003        int nextIndex;
3004        boolean inActivity = false, inService = false;
3005        if (hasActivity) {
3006            // Process has activities, put it at the very tipsy-top.
3007            addIndex = mLruProcesses.size();
3008            nextIndex = mLruProcessServiceStart;
3009            inActivity = true;
3010        } else if (hasService) {
3011            // Process has services, put it at the top of the service list.
3012            addIndex = mLruProcessActivityStart;
3013            nextIndex = mLruProcessServiceStart;
3014            inActivity = true;
3015            inService = true;
3016        } else  {
3017            // Process not otherwise of interest, it goes to the top of the non-service area.
3018            addIndex = mLruProcessServiceStart;
3019            if (client != null) {
3020                int clientIndex = mLruProcesses.lastIndexOf(client);
3021                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3022                        + app);
3023                if (clientIndex >= 0 && addIndex > clientIndex) {
3024                    addIndex = clientIndex;
3025                }
3026            }
3027            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3028        }
3029
3030        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3031                + mLruProcessActivityStart + "): " + app);
3032        */
3033
3034        if (lrui >= 0) {
3035            if (lrui < mLruProcessActivityStart) {
3036                mLruProcessActivityStart--;
3037            }
3038            if (lrui < mLruProcessServiceStart) {
3039                mLruProcessServiceStart--;
3040            }
3041            /*
3042            if (addIndex > lrui) {
3043                addIndex--;
3044            }
3045            if (nextIndex > lrui) {
3046                nextIndex--;
3047            }
3048            */
3049            mLruProcesses.remove(lrui);
3050        }
3051
3052        /*
3053        mLruProcesses.add(addIndex, app);
3054        if (inActivity) {
3055            mLruProcessActivityStart++;
3056        }
3057        if (inService) {
3058            mLruProcessActivityStart++;
3059        }
3060        */
3061
3062        int nextIndex;
3063        if (hasActivity) {
3064            final int N = mLruProcesses.size();
3065            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3066                // Process doesn't have activities, but has clients with
3067                // activities...  move it up, but one below the top (the top
3068                // should always have a real activity).
3069                if (DEBUG_LRU) Slog.d(TAG_LRU,
3070                        "Adding to second-top of LRU activity list: " + app);
3071                mLruProcesses.add(N - 1, app);
3072                // To keep it from spamming the LRU list (by making a bunch of clients),
3073                // we will push down any other entries owned by the app.
3074                final int uid = app.info.uid;
3075                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3076                    ProcessRecord subProc = mLruProcesses.get(i);
3077                    if (subProc.info.uid == uid) {
3078                        // We want to push this one down the list.  If the process after
3079                        // it is for the same uid, however, don't do so, because we don't
3080                        // want them internally to be re-ordered.
3081                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3082                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3083                                    "Pushing uid " + uid + " swapping at " + i + ": "
3084                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3085                            ProcessRecord tmp = mLruProcesses.get(i);
3086                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3087                            mLruProcesses.set(i - 1, tmp);
3088                            i--;
3089                        }
3090                    } else {
3091                        // A gap, we can stop here.
3092                        break;
3093                    }
3094                }
3095            } else {
3096                // Process has activities, put it at the very tipsy-top.
3097                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3098                mLruProcesses.add(app);
3099            }
3100            nextIndex = mLruProcessServiceStart;
3101        } else if (hasService) {
3102            // Process has services, put it at the top of the service list.
3103            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3104            mLruProcesses.add(mLruProcessActivityStart, app);
3105            nextIndex = mLruProcessServiceStart;
3106            mLruProcessActivityStart++;
3107        } else  {
3108            // Process not otherwise of interest, it goes to the top of the non-service area.
3109            int index = mLruProcessServiceStart;
3110            if (client != null) {
3111                // If there is a client, don't allow the process to be moved up higher
3112                // in the list than that client.
3113                int clientIndex = mLruProcesses.lastIndexOf(client);
3114                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3115                        + " when updating " + app);
3116                if (clientIndex <= lrui) {
3117                    // Don't allow the client index restriction to push it down farther in the
3118                    // list than it already is.
3119                    clientIndex = lrui;
3120                }
3121                if (clientIndex >= 0 && index > clientIndex) {
3122                    index = clientIndex;
3123                }
3124            }
3125            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3126            mLruProcesses.add(index, app);
3127            nextIndex = index-1;
3128            mLruProcessActivityStart++;
3129            mLruProcessServiceStart++;
3130        }
3131
3132        // If the app is currently using a content provider or service,
3133        // bump those processes as well.
3134        for (int j=app.connections.size()-1; j>=0; j--) {
3135            ConnectionRecord cr = app.connections.valueAt(j);
3136            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3137                    && cr.binding.service.app != null
3138                    && cr.binding.service.app.lruSeq != mLruSeq
3139                    && !cr.binding.service.app.persistent) {
3140                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3141                        "service connection", cr, app);
3142            }
3143        }
3144        for (int j=app.conProviders.size()-1; j>=0; j--) {
3145            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3146            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3147                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3148                        "provider reference", cpr, app);
3149            }
3150        }
3151    }
3152
3153    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3154        if (uid == Process.SYSTEM_UID) {
3155            // The system gets to run in any process.  If there are multiple
3156            // processes with the same uid, just pick the first (this
3157            // should never happen).
3158            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3159            if (procs == null) return null;
3160            final int procCount = procs.size();
3161            for (int i = 0; i < procCount; i++) {
3162                final int procUid = procs.keyAt(i);
3163                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3164                    // Don't use an app process or different user process for system component.
3165                    continue;
3166                }
3167                return procs.valueAt(i);
3168            }
3169        }
3170        ProcessRecord proc = mProcessNames.get(processName, uid);
3171        if (false && proc != null && !keepIfLarge
3172                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3173                && proc.lastCachedPss >= 4000) {
3174            // Turn this condition on to cause killing to happen regularly, for testing.
3175            if (proc.baseProcessTracker != null) {
3176                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3177            }
3178            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3179        } else if (proc != null && !keepIfLarge
3180                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3181                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3182            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3183            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3184                if (proc.baseProcessTracker != null) {
3185                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3186                }
3187                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3188            }
3189        }
3190        return proc;
3191    }
3192
3193    void notifyPackageUse(String packageName) {
3194        IPackageManager pm = AppGlobals.getPackageManager();
3195        try {
3196            pm.notifyPackageUse(packageName);
3197        } catch (RemoteException e) {
3198        }
3199    }
3200
3201    boolean isNextTransitionForward() {
3202        int transit = mWindowManager.getPendingAppTransition();
3203        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3204                || transit == AppTransition.TRANSIT_TASK_OPEN
3205                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3206    }
3207
3208    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3209            String processName, String abiOverride, int uid, Runnable crashHandler) {
3210        synchronized(this) {
3211            ApplicationInfo info = new ApplicationInfo();
3212            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3213            // For isolated processes, the former contains the parent's uid and the latter the
3214            // actual uid of the isolated process.
3215            // In the special case introduced by this method (which is, starting an isolated
3216            // process directly from the SystemServer without an actual parent app process) the
3217            // closest thing to a parent's uid is SYSTEM_UID.
3218            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3219            // the |isolated| logic in the ProcessRecord constructor.
3220            info.uid = Process.SYSTEM_UID;
3221            info.processName = processName;
3222            info.className = entryPoint;
3223            info.packageName = "android";
3224            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3225                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3226                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3227                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3228                    crashHandler);
3229            return proc != null ? proc.pid : 0;
3230        }
3231    }
3232
3233    final ProcessRecord startProcessLocked(String processName,
3234            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3235            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3236            boolean isolated, boolean keepIfLarge) {
3237        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3238                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3239                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3240                null /* crashHandler */);
3241    }
3242
3243    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3244            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3245            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3246            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3247        long startTime = SystemClock.elapsedRealtime();
3248        ProcessRecord app;
3249        if (!isolated) {
3250            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3251            checkTime(startTime, "startProcess: after getProcessRecord");
3252
3253            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3254                // If we are in the background, then check to see if this process
3255                // is bad.  If so, we will just silently fail.
3256                if (mAppErrors.isBadProcessLocked(info)) {
3257                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3258                            + "/" + info.processName);
3259                    return null;
3260                }
3261            } else {
3262                // When the user is explicitly starting a process, then clear its
3263                // crash count so that we won't make it bad until they see at
3264                // least one crash dialog again, and make the process good again
3265                // if it had been bad.
3266                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3267                        + "/" + info.processName);
3268                mAppErrors.resetProcessCrashTimeLocked(info);
3269                if (mAppErrors.isBadProcessLocked(info)) {
3270                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3271                            UserHandle.getUserId(info.uid), info.uid,
3272                            info.processName);
3273                    mAppErrors.clearBadProcessLocked(info);
3274                    if (app != null) {
3275                        app.bad = false;
3276                    }
3277                }
3278            }
3279        } else {
3280            // If this is an isolated process, it can't re-use an existing process.
3281            app = null;
3282        }
3283
3284        // app launch boost for big.little configurations
3285        // use cpusets to migrate freshly launched tasks to big cores
3286        synchronized(ActivityManagerService.this) {
3287            nativeMigrateToBoost();
3288            mIsBoosted = true;
3289            mBoostStartTime = SystemClock.uptimeMillis();
3290            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3291            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3292        }
3293
3294        // We don't have to do anything more if:
3295        // (1) There is an existing application record; and
3296        // (2) The caller doesn't think it is dead, OR there is no thread
3297        //     object attached to it so we know it couldn't have crashed; and
3298        // (3) There is a pid assigned to it, so it is either starting or
3299        //     already running.
3300        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3301                + " app=" + app + " knownToBeDead=" + knownToBeDead
3302                + " thread=" + (app != null ? app.thread : null)
3303                + " pid=" + (app != null ? app.pid : -1));
3304        if (app != null && app.pid > 0) {
3305            if (!knownToBeDead || app.thread == null) {
3306                // We already have the app running, or are waiting for it to
3307                // come up (we have a pid but not yet its thread), so keep it.
3308                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3309                // If this is a new package in the process, add the package to the list
3310                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3311                checkTime(startTime, "startProcess: done, added package to proc");
3312                return app;
3313            }
3314
3315            // An application record is attached to a previous process,
3316            // clean it up now.
3317            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3318            checkTime(startTime, "startProcess: bad proc running, killing");
3319            killProcessGroup(app.info.uid, app.pid);
3320            handleAppDiedLocked(app, true, true);
3321            checkTime(startTime, "startProcess: done killing old proc");
3322        }
3323
3324        String hostingNameStr = hostingName != null
3325                ? hostingName.flattenToShortString() : null;
3326
3327        if (app == null) {
3328            checkTime(startTime, "startProcess: creating new process record");
3329            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3330            if (app == null) {
3331                Slog.w(TAG, "Failed making new process record for "
3332                        + processName + "/" + info.uid + " isolated=" + isolated);
3333                return null;
3334            }
3335            app.crashHandler = crashHandler;
3336            checkTime(startTime, "startProcess: done creating new process record");
3337        } else {
3338            // If this is a new package in the process, add the package to the list
3339            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3340            checkTime(startTime, "startProcess: added package to existing proc");
3341        }
3342
3343        // If the system is not ready yet, then hold off on starting this
3344        // process until it is.
3345        if (!mProcessesReady
3346                && !isAllowedWhileBooting(info)
3347                && !allowWhileBooting) {
3348            if (!mProcessesOnHold.contains(app)) {
3349                mProcessesOnHold.add(app);
3350            }
3351            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3352                    "System not ready, putting on hold: " + app);
3353            checkTime(startTime, "startProcess: returning with proc on hold");
3354            return app;
3355        }
3356
3357        checkTime(startTime, "startProcess: stepping in to startProcess");
3358        startProcessLocked(
3359                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3360        checkTime(startTime, "startProcess: done starting proc!");
3361        return (app.pid != 0) ? app : null;
3362    }
3363
3364    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3365        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3366    }
3367
3368    private final void startProcessLocked(ProcessRecord app,
3369            String hostingType, String hostingNameStr) {
3370        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3371                null /* entryPoint */, null /* entryPointArgs */);
3372    }
3373
3374    private final void startProcessLocked(ProcessRecord app, String hostingType,
3375            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3376        long startTime = SystemClock.elapsedRealtime();
3377        if (app.pid > 0 && app.pid != MY_PID) {
3378            checkTime(startTime, "startProcess: removing from pids map");
3379            synchronized (mPidsSelfLocked) {
3380                mPidsSelfLocked.remove(app.pid);
3381                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3382            }
3383            checkTime(startTime, "startProcess: done removing from pids map");
3384            app.setPid(0);
3385        }
3386
3387        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3388                "startProcessLocked removing on hold: " + app);
3389        mProcessesOnHold.remove(app);
3390
3391        checkTime(startTime, "startProcess: starting to update cpu stats");
3392        updateCpuStats();
3393        checkTime(startTime, "startProcess: done updating cpu stats");
3394
3395        try {
3396            try {
3397                final int userId = UserHandle.getUserId(app.uid);
3398                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3399            } catch (RemoteException e) {
3400                throw e.rethrowAsRuntimeException();
3401            }
3402
3403            int uid = app.uid;
3404            int[] gids = null;
3405            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3406            if (!app.isolated) {
3407                int[] permGids = null;
3408                try {
3409                    checkTime(startTime, "startProcess: getting gids from package manager");
3410                    final IPackageManager pm = AppGlobals.getPackageManager();
3411                    permGids = pm.getPackageGids(app.info.packageName,
3412                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3413                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3414                            MountServiceInternal.class);
3415                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3416                            app.info.packageName);
3417                } catch (RemoteException e) {
3418                    throw e.rethrowAsRuntimeException();
3419                }
3420
3421                /*
3422                 * Add shared application and profile GIDs so applications can share some
3423                 * resources like shared libraries and access user-wide resources
3424                 */
3425                if (ArrayUtils.isEmpty(permGids)) {
3426                    gids = new int[2];
3427                } else {
3428                    gids = new int[permGids.length + 2];
3429                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3430                }
3431                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3432                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3433            }
3434            checkTime(startTime, "startProcess: building args");
3435            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3436                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3437                        && mTopComponent != null
3438                        && app.processName.equals(mTopComponent.getPackageName())) {
3439                    uid = 0;
3440                }
3441                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3442                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3443                    uid = 0;
3444                }
3445            }
3446            int debugFlags = 0;
3447            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3448                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3449                // Also turn on CheckJNI for debuggable apps. It's quite
3450                // awkward to turn on otherwise.
3451                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3452            }
3453            // Run the app in safe mode if its manifest requests so or the
3454            // system is booted in safe mode.
3455            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3456                mSafeMode == true) {
3457                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3458            }
3459            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3460                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3461            }
3462            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3463            if ("true".equals(genDebugInfoProperty)) {
3464                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3465            }
3466            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3467                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3468            }
3469            if ("1".equals(SystemProperties.get("debug.assert"))) {
3470                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3471            }
3472
3473            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3474            if (requiredAbi == null) {
3475                requiredAbi = Build.SUPPORTED_ABIS[0];
3476            }
3477
3478            String instructionSet = null;
3479            if (app.info.primaryCpuAbi != null) {
3480                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3481            }
3482
3483            app.gids = gids;
3484            app.requiredAbi = requiredAbi;
3485            app.instructionSet = instructionSet;
3486
3487            // Start the process.  It will either succeed and return a result containing
3488            // the PID of the new process, or else throw a RuntimeException.
3489            boolean isActivityProcess = (entryPoint == null);
3490            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3491            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3492                    app.processName);
3493            checkTime(startTime, "startProcess: asking zygote to start proc");
3494            Process.ProcessStartResult startResult = Process.start(entryPoint,
3495                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3496                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3497                    app.info.dataDir, entryPointArgs);
3498            checkTime(startTime, "startProcess: returned from zygote!");
3499            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3500
3501            if (app.isolated) {
3502                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3503            }
3504            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3505            checkTime(startTime, "startProcess: done updating battery stats");
3506
3507            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3508                    UserHandle.getUserId(uid), startResult.pid, uid,
3509                    app.processName, hostingType,
3510                    hostingNameStr != null ? hostingNameStr : "");
3511
3512            mProcessStartLogger.logIfNeededLocked(app, startResult);
3513
3514            if (app.persistent) {
3515                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3516            }
3517
3518            if (DEBUG_PROCESSES) {
3519                checkTime(startTime, "startProcess: building log message");
3520                StringBuilder buf = mStringBuilder;
3521                buf.setLength(0);
3522                buf.append("Start proc ");
3523                buf.append(startResult.pid);
3524                buf.append(':');
3525                buf.append(app.processName);
3526                buf.append('/');
3527                UserHandle.formatUid(buf, uid);
3528                if (!isActivityProcess) {
3529                    buf.append(" [");
3530                    buf.append(entryPoint);
3531                    buf.append("]");
3532                }
3533                buf.append(" for ");
3534                buf.append(hostingType);
3535                if (hostingNameStr != null) {
3536                    buf.append(" ");
3537                    buf.append(hostingNameStr);
3538                }
3539                Slog.i(TAG, buf.toString());
3540            }
3541            app.setPid(startResult.pid);
3542            app.usingWrapper = startResult.usingWrapper;
3543            app.removed = false;
3544            app.killed = false;
3545            app.killedByAm = false;
3546            checkTime(startTime, "startProcess: starting to update pids map");
3547            synchronized (mPidsSelfLocked) {
3548                this.mPidsSelfLocked.put(startResult.pid, app);
3549                if (isActivityProcess) {
3550                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3551                    msg.obj = app;
3552                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3553                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3554                }
3555            }
3556            checkTime(startTime, "startProcess: done updating pids map");
3557        } catch (RuntimeException e) {
3558            // XXX do better error recovery.
3559            app.setPid(0);
3560            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3561            if (app.isolated) {
3562                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3563            }
3564            Slog.e(TAG, "Failure starting process " + app.processName, e);
3565        }
3566    }
3567
3568    void updateUsageStats(ActivityRecord component, boolean resumed) {
3569        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3570                "updateUsageStats: comp=" + component + "res=" + resumed);
3571        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3572        if (resumed) {
3573            if (mUsageStatsService != null) {
3574                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3575                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3576            }
3577            synchronized (stats) {
3578                stats.noteActivityResumedLocked(component.app.uid);
3579            }
3580        } else {
3581            if (mUsageStatsService != null) {
3582                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3583                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3584            }
3585            synchronized (stats) {
3586                stats.noteActivityPausedLocked(component.app.uid);
3587            }
3588        }
3589    }
3590
3591    Intent getHomeIntent() {
3592        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3593        intent.setComponent(mTopComponent);
3594        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3595        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3596            intent.addCategory(Intent.CATEGORY_HOME);
3597        }
3598        return intent;
3599    }
3600
3601    boolean startHomeActivityLocked(int userId, String reason) {
3602        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3603                && mTopAction == null) {
3604            // We are running in factory test mode, but unable to find
3605            // the factory test app, so just sit around displaying the
3606            // error message and don't try to start anything.
3607            return false;
3608        }
3609        Intent intent = getHomeIntent();
3610        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3611        if (aInfo != null) {
3612            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3613            // Don't do this if the home app is currently being
3614            // instrumented.
3615            aInfo = new ActivityInfo(aInfo);
3616            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3617            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3618                    aInfo.applicationInfo.uid, true);
3619            if (app == null || app.instrumentationClass == null) {
3620                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3621                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3622            }
3623        }
3624
3625        return true;
3626    }
3627
3628    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3629        ActivityInfo ai = null;
3630        ComponentName comp = intent.getComponent();
3631        try {
3632            if (comp != null) {
3633                // Factory test.
3634                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3635            } else {
3636                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3637                        intent,
3638                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3639                        flags, userId);
3640
3641                if (info != null) {
3642                    ai = info.activityInfo;
3643                }
3644            }
3645        } catch (RemoteException e) {
3646            // ignore
3647        }
3648
3649        return ai;
3650    }
3651
3652    /**
3653     * Starts the "new version setup screen" if appropriate.
3654     */
3655    void startSetupActivityLocked() {
3656        // Only do this once per boot.
3657        if (mCheckedForSetup) {
3658            return;
3659        }
3660
3661        // We will show this screen if the current one is a different
3662        // version than the last one shown, and we are not running in
3663        // low-level factory test mode.
3664        final ContentResolver resolver = mContext.getContentResolver();
3665        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3666                Settings.Global.getInt(resolver,
3667                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3668            mCheckedForSetup = true;
3669
3670            // See if we should be showing the platform update setup UI.
3671            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3672            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3673                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3674            if (!ris.isEmpty()) {
3675                final ResolveInfo ri = ris.get(0);
3676                String vers = ri.activityInfo.metaData != null
3677                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3678                        : null;
3679                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3680                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3681                            Intent.METADATA_SETUP_VERSION);
3682                }
3683                String lastVers = Settings.Secure.getString(
3684                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3685                if (vers != null && !vers.equals(lastVers)) {
3686                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3687                    intent.setComponent(new ComponentName(
3688                            ri.activityInfo.packageName, ri.activityInfo.name));
3689                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3690                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3691                            null, 0, 0, 0, null, false, false, null, null, null);
3692                }
3693            }
3694        }
3695    }
3696
3697    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3698        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3699    }
3700
3701    void enforceNotIsolatedCaller(String caller) {
3702        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3703            throw new SecurityException("Isolated process not allowed to call " + caller);
3704        }
3705    }
3706
3707    void enforceShellRestriction(String restriction, int userHandle) {
3708        if (Binder.getCallingUid() == Process.SHELL_UID) {
3709            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3710                throw new SecurityException("Shell does not have permission to access user "
3711                        + userHandle);
3712            }
3713        }
3714    }
3715
3716    @Override
3717    public int getFrontActivityScreenCompatMode() {
3718        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3719        synchronized (this) {
3720            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3721        }
3722    }
3723
3724    @Override
3725    public void setFrontActivityScreenCompatMode(int mode) {
3726        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3727                "setFrontActivityScreenCompatMode");
3728        synchronized (this) {
3729            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3730        }
3731    }
3732
3733    @Override
3734    public int getPackageScreenCompatMode(String packageName) {
3735        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3736        synchronized (this) {
3737            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3738        }
3739    }
3740
3741    @Override
3742    public void setPackageScreenCompatMode(String packageName, int mode) {
3743        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3744                "setPackageScreenCompatMode");
3745        synchronized (this) {
3746            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3747        }
3748    }
3749
3750    @Override
3751    public boolean getPackageAskScreenCompat(String packageName) {
3752        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3753        synchronized (this) {
3754            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3755        }
3756    }
3757
3758    @Override
3759    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3760        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3761                "setPackageAskScreenCompat");
3762        synchronized (this) {
3763            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3764        }
3765    }
3766
3767    private boolean hasUsageStatsPermission(String callingPackage) {
3768        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3769                Binder.getCallingUid(), callingPackage);
3770        if (mode == AppOpsManager.MODE_DEFAULT) {
3771            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3772                    == PackageManager.PERMISSION_GRANTED;
3773        }
3774        return mode == AppOpsManager.MODE_ALLOWED;
3775    }
3776
3777    @Override
3778    public int getPackageProcessState(String packageName, String callingPackage) {
3779        if (!hasUsageStatsPermission(callingPackage)) {
3780            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3781                    "getPackageProcessState");
3782        }
3783
3784        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3785        synchronized (this) {
3786            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3787                final ProcessRecord proc = mLruProcesses.get(i);
3788                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3789                        || procState > proc.setProcState) {
3790                    boolean found = false;
3791                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3792                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3793                            procState = proc.setProcState;
3794                            found = true;
3795                        }
3796                    }
3797                    if (proc.pkgDeps != null && !found) {
3798                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3799                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3800                                procState = proc.setProcState;
3801                                break;
3802                            }
3803                        }
3804                    }
3805                }
3806            }
3807        }
3808        return procState;
3809    }
3810
3811    @Override
3812    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3813        synchronized (this) {
3814            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3815            if (app == null) {
3816                return false;
3817            }
3818            if (app.trimMemoryLevel < level && app.thread != null &&
3819                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3820                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3821                try {
3822                    app.thread.scheduleTrimMemory(level);
3823                    app.trimMemoryLevel = level;
3824                    return true;
3825                } catch (RemoteException e) {
3826                    // Fallthrough to failure case.
3827                }
3828            }
3829        }
3830        return false;
3831    }
3832
3833    private void dispatchProcessesChanged() {
3834        int N;
3835        synchronized (this) {
3836            N = mPendingProcessChanges.size();
3837            if (mActiveProcessChanges.length < N) {
3838                mActiveProcessChanges = new ProcessChangeItem[N];
3839            }
3840            mPendingProcessChanges.toArray(mActiveProcessChanges);
3841            mPendingProcessChanges.clear();
3842            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3843                    "*** Delivering " + N + " process changes");
3844        }
3845
3846        int i = mProcessObservers.beginBroadcast();
3847        while (i > 0) {
3848            i--;
3849            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3850            if (observer != null) {
3851                try {
3852                    for (int j=0; j<N; j++) {
3853                        ProcessChangeItem item = mActiveProcessChanges[j];
3854                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3855                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3856                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3857                                    + item.uid + ": " + item.foregroundActivities);
3858                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3859                                    item.foregroundActivities);
3860                        }
3861                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3862                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3863                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3864                                    + ": " + item.processState);
3865                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3866                        }
3867                    }
3868                } catch (RemoteException e) {
3869                }
3870            }
3871        }
3872        mProcessObservers.finishBroadcast();
3873
3874        synchronized (this) {
3875            for (int j=0; j<N; j++) {
3876                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3877            }
3878        }
3879    }
3880
3881    private void dispatchProcessDied(int pid, int uid) {
3882        int i = mProcessObservers.beginBroadcast();
3883        while (i > 0) {
3884            i--;
3885            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3886            if (observer != null) {
3887                try {
3888                    observer.onProcessDied(pid, uid);
3889                } catch (RemoteException e) {
3890                }
3891            }
3892        }
3893        mProcessObservers.finishBroadcast();
3894    }
3895
3896    private void dispatchUidsChanged() {
3897        int N;
3898        synchronized (this) {
3899            N = mPendingUidChanges.size();
3900            if (mActiveUidChanges.length < N) {
3901                mActiveUidChanges = new UidRecord.ChangeItem[N];
3902            }
3903            for (int i=0; i<N; i++) {
3904                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3905                mActiveUidChanges[i] = change;
3906                if (change.uidRecord != null) {
3907                    change.uidRecord.pendingChange = null;
3908                    change.uidRecord = null;
3909                }
3910            }
3911            mPendingUidChanges.clear();
3912            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3913                    "*** Delivering " + N + " uid changes");
3914        }
3915
3916        if (mLocalPowerManager != null) {
3917            for (int j=0; j<N; j++) {
3918                UidRecord.ChangeItem item = mActiveUidChanges[j];
3919                if (item.change == UidRecord.CHANGE_GONE
3920                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3921                    mLocalPowerManager.uidGone(item.uid);
3922                } else {
3923                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3924                }
3925            }
3926        }
3927
3928        int i = mUidObservers.beginBroadcast();
3929        while (i > 0) {
3930            i--;
3931            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3932            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3933            if (observer != null) {
3934                try {
3935                    for (int j=0; j<N; j++) {
3936                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3937                        final int change = item.change;
3938                        UidRecord validateUid = null;
3939                        if (VALIDATE_UID_STATES && i == 0) {
3940                            validateUid = mValidateUids.get(item.uid);
3941                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3942                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3943                                validateUid = new UidRecord(item.uid);
3944                                mValidateUids.put(item.uid, validateUid);
3945                            }
3946                        }
3947                        if (change == UidRecord.CHANGE_IDLE
3948                                || change == UidRecord.CHANGE_GONE_IDLE) {
3949                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3950                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3951                                        "UID idle uid=" + item.uid);
3952                                observer.onUidIdle(item.uid);
3953                            }
3954                            if (VALIDATE_UID_STATES && i == 0) {
3955                                if (validateUid != null) {
3956                                    validateUid.idle = true;
3957                                }
3958                            }
3959                        } else if (change == UidRecord.CHANGE_ACTIVE) {
3960                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3961                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3962                                        "UID active uid=" + item.uid);
3963                                observer.onUidActive(item.uid);
3964                            }
3965                            if (VALIDATE_UID_STATES && i == 0) {
3966                                validateUid.idle = false;
3967                            }
3968                        }
3969                        if (change == UidRecord.CHANGE_GONE
3970                                || change == UidRecord.CHANGE_GONE_IDLE) {
3971                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
3972                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3973                                        "UID gone uid=" + item.uid);
3974                                observer.onUidGone(item.uid);
3975                            }
3976                            if (VALIDATE_UID_STATES && i == 0) {
3977                                if (validateUid != null) {
3978                                    mValidateUids.remove(item.uid);
3979                                }
3980                            }
3981                        } else {
3982                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
3983                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3984                                        "UID CHANGED uid=" + item.uid
3985                                                + ": " + item.processState);
3986                                observer.onUidStateChanged(item.uid, item.processState);
3987                            }
3988                            if (VALIDATE_UID_STATES && i == 0) {
3989                                validateUid.curProcState = validateUid.setProcState
3990                                        = item.processState;
3991                            }
3992                        }
3993                    }
3994                } catch (RemoteException e) {
3995                }
3996            }
3997        }
3998        mUidObservers.finishBroadcast();
3999
4000        synchronized (this) {
4001            for (int j=0; j<N; j++) {
4002                mAvailUidChanges.add(mActiveUidChanges[j]);
4003            }
4004        }
4005    }
4006
4007    @Override
4008    public final int startActivity(IApplicationThread caller, String callingPackage,
4009            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4010            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4011        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4012                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4013                UserHandle.getCallingUserId());
4014    }
4015
4016    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4017        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4018        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4019                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4020                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4021
4022        // TODO: Switch to user app stacks here.
4023        String mimeType = intent.getType();
4024        final Uri data = intent.getData();
4025        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4026            mimeType = getProviderMimeType(data, userId);
4027        }
4028        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4029
4030        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4031        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4032                null, 0, 0, null, null, null, null, false, userId, container, null);
4033    }
4034
4035    @Override
4036    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4037            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4038            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4039        enforceNotIsolatedCaller("startActivity");
4040        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4041                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4042        // TODO: Switch to user app stacks here.
4043        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4044                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4045                profilerInfo, null, null, bOptions, false, userId, null, null);
4046    }
4047
4048    @Override
4049    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4050            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4051            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4052            int userId) {
4053
4054        // This is very dangerous -- it allows you to perform a start activity (including
4055        // permission grants) as any app that may launch one of your own activities.  So
4056        // we will only allow this to be done from activities that are part of the core framework,
4057        // and then only when they are running as the system.
4058        final ActivityRecord sourceRecord;
4059        final int targetUid;
4060        final String targetPackage;
4061        synchronized (this) {
4062            if (resultTo == null) {
4063                throw new SecurityException("Must be called from an activity");
4064            }
4065            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4066            if (sourceRecord == null) {
4067                throw new SecurityException("Called with bad activity token: " + resultTo);
4068            }
4069            if (!sourceRecord.info.packageName.equals("android")) {
4070                throw new SecurityException(
4071                        "Must be called from an activity that is declared in the android package");
4072            }
4073            if (sourceRecord.app == null) {
4074                throw new SecurityException("Called without a process attached to activity");
4075            }
4076            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4077                // This is still okay, as long as this activity is running under the
4078                // uid of the original calling activity.
4079                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4080                    throw new SecurityException(
4081                            "Calling activity in uid " + sourceRecord.app.uid
4082                                    + " must be system uid or original calling uid "
4083                                    + sourceRecord.launchedFromUid);
4084                }
4085            }
4086            if (ignoreTargetSecurity) {
4087                if (intent.getComponent() == null) {
4088                    throw new SecurityException(
4089                            "Component must be specified with ignoreTargetSecurity");
4090                }
4091                if (intent.getSelector() != null) {
4092                    throw new SecurityException(
4093                            "Selector not allowed with ignoreTargetSecurity");
4094                }
4095            }
4096            targetUid = sourceRecord.launchedFromUid;
4097            targetPackage = sourceRecord.launchedFromPackage;
4098        }
4099
4100        if (userId == UserHandle.USER_NULL) {
4101            userId = UserHandle.getUserId(sourceRecord.app.uid);
4102        }
4103
4104        // TODO: Switch to user app stacks here.
4105        try {
4106            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4107                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4108                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4109            return ret;
4110        } catch (SecurityException e) {
4111            // XXX need to figure out how to propagate to original app.
4112            // A SecurityException here is generally actually a fault of the original
4113            // calling activity (such as a fairly granting permissions), so propagate it
4114            // back to them.
4115            /*
4116            StringBuilder msg = new StringBuilder();
4117            msg.append("While launching");
4118            msg.append(intent.toString());
4119            msg.append(": ");
4120            msg.append(e.getMessage());
4121            */
4122            throw e;
4123        }
4124    }
4125
4126    @Override
4127    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4128            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4129            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4130        enforceNotIsolatedCaller("startActivityAndWait");
4131        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4132                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4133        WaitResult res = new WaitResult();
4134        // TODO: Switch to user app stacks here.
4135        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4136                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4137                bOptions, false, userId, null, null);
4138        return res;
4139    }
4140
4141    @Override
4142    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4143            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4144            int startFlags, Configuration config, Bundle bOptions, int userId) {
4145        enforceNotIsolatedCaller("startActivityWithConfig");
4146        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4147                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4148        // TODO: Switch to user app stacks here.
4149        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4150                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4151                null, null, config, bOptions, false, userId, null, null);
4152        return ret;
4153    }
4154
4155    @Override
4156    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4157            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4158            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4159            throws TransactionTooLargeException {
4160        enforceNotIsolatedCaller("startActivityIntentSender");
4161        // Refuse possible leaked file descriptors
4162        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4163            throw new IllegalArgumentException("File descriptors passed in Intent");
4164        }
4165
4166        IIntentSender sender = intent.getTarget();
4167        if (!(sender instanceof PendingIntentRecord)) {
4168            throw new IllegalArgumentException("Bad PendingIntent object");
4169        }
4170
4171        PendingIntentRecord pir = (PendingIntentRecord)sender;
4172
4173        synchronized (this) {
4174            // If this is coming from the currently resumed activity, it is
4175            // effectively saying that app switches are allowed at this point.
4176            final ActivityStack stack = getFocusedStack();
4177            if (stack.mResumedActivity != null &&
4178                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4179                mAppSwitchesAllowedTime = 0;
4180            }
4181        }
4182        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4183                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4184        return ret;
4185    }
4186
4187    @Override
4188    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4189            Intent intent, String resolvedType, IVoiceInteractionSession session,
4190            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4191            Bundle bOptions, int userId) {
4192        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4193                != PackageManager.PERMISSION_GRANTED) {
4194            String msg = "Permission Denial: startVoiceActivity() from pid="
4195                    + Binder.getCallingPid()
4196                    + ", uid=" + Binder.getCallingUid()
4197                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4198            Slog.w(TAG, msg);
4199            throw new SecurityException(msg);
4200        }
4201        if (session == null || interactor == null) {
4202            throw new NullPointerException("null session or interactor");
4203        }
4204        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4205                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4206        // TODO: Switch to user app stacks here.
4207        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4208                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4209                null, bOptions, false, userId, null, null);
4210    }
4211
4212    @Override
4213    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4214            throws RemoteException {
4215        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4216        synchronized (this) {
4217            ActivityRecord activity = getFocusedStack().topActivity();
4218            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4219                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4220            }
4221            if (mRunningVoice != null || activity.task.voiceSession != null
4222                    || activity.voiceSession != null) {
4223                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4224                return;
4225            }
4226            if (activity.pendingVoiceInteractionStart) {
4227                Slog.w(TAG, "Pending start of voice interaction already.");
4228                return;
4229            }
4230            activity.pendingVoiceInteractionStart = true;
4231        }
4232        LocalServices.getService(VoiceInteractionManagerInternal.class)
4233                .startLocalVoiceInteraction(callingActivity, options);
4234    }
4235
4236    @Override
4237    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4238        LocalServices.getService(VoiceInteractionManagerInternal.class)
4239                .stopLocalVoiceInteraction(callingActivity);
4240    }
4241
4242    @Override
4243    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4244        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4245                .supportsLocalVoiceInteraction();
4246    }
4247
4248    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4249            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4250        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4251        if (activityToCallback == null) return;
4252        activityToCallback.setVoiceSessionLocked(voiceSession);
4253
4254        // Inform the activity
4255        try {
4256            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4257                    voiceInteractor);
4258            long token = Binder.clearCallingIdentity();
4259            try {
4260                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4261            } finally {
4262                Binder.restoreCallingIdentity(token);
4263            }
4264            // TODO: VI Should we cache the activity so that it's easier to find later
4265            // rather than scan through all the stacks and activities?
4266        } catch (RemoteException re) {
4267            activityToCallback.clearVoiceSessionLocked();
4268            // TODO: VI Should this terminate the voice session?
4269        }
4270    }
4271
4272    @Override
4273    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4274        synchronized (this) {
4275            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4276                if (keepAwake) {
4277                    mVoiceWakeLock.acquire();
4278                } else {
4279                    mVoiceWakeLock.release();
4280                }
4281            }
4282        }
4283    }
4284
4285    @Override
4286    public boolean startNextMatchingActivity(IBinder callingActivity,
4287            Intent intent, Bundle bOptions) {
4288        // Refuse possible leaked file descriptors
4289        if (intent != null && intent.hasFileDescriptors() == true) {
4290            throw new IllegalArgumentException("File descriptors passed in Intent");
4291        }
4292        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4293
4294        synchronized (this) {
4295            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4296            if (r == null) {
4297                ActivityOptions.abort(options);
4298                return false;
4299            }
4300            if (r.app == null || r.app.thread == null) {
4301                // The caller is not running...  d'oh!
4302                ActivityOptions.abort(options);
4303                return false;
4304            }
4305            intent = new Intent(intent);
4306            // The caller is not allowed to change the data.
4307            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4308            // And we are resetting to find the next component...
4309            intent.setComponent(null);
4310
4311            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4312
4313            ActivityInfo aInfo = null;
4314            try {
4315                List<ResolveInfo> resolves =
4316                    AppGlobals.getPackageManager().queryIntentActivities(
4317                            intent, r.resolvedType,
4318                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4319                            UserHandle.getCallingUserId());
4320
4321                // Look for the original activity in the list...
4322                final int N = resolves != null ? resolves.size() : 0;
4323                for (int i=0; i<N; i++) {
4324                    ResolveInfo rInfo = resolves.get(i);
4325                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4326                            && rInfo.activityInfo.name.equals(r.info.name)) {
4327                        // We found the current one...  the next matching is
4328                        // after it.
4329                        i++;
4330                        if (i<N) {
4331                            aInfo = resolves.get(i).activityInfo;
4332                        }
4333                        if (debug) {
4334                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4335                                    + "/" + r.info.name);
4336                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4337                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4338                        }
4339                        break;
4340                    }
4341                }
4342            } catch (RemoteException e) {
4343            }
4344
4345            if (aInfo == null) {
4346                // Nobody who is next!
4347                ActivityOptions.abort(options);
4348                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4349                return false;
4350            }
4351
4352            intent.setComponent(new ComponentName(
4353                    aInfo.applicationInfo.packageName, aInfo.name));
4354            intent.setFlags(intent.getFlags()&~(
4355                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4356                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4357                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4358                    Intent.FLAG_ACTIVITY_NEW_TASK));
4359
4360            // Okay now we need to start the new activity, replacing the
4361            // currently running activity.  This is a little tricky because
4362            // we want to start the new one as if the current one is finished,
4363            // but not finish the current one first so that there is no flicker.
4364            // And thus...
4365            final boolean wasFinishing = r.finishing;
4366            r.finishing = true;
4367
4368            // Propagate reply information over to the new activity.
4369            final ActivityRecord resultTo = r.resultTo;
4370            final String resultWho = r.resultWho;
4371            final int requestCode = r.requestCode;
4372            r.resultTo = null;
4373            if (resultTo != null) {
4374                resultTo.removeResultsLocked(r, resultWho, requestCode);
4375            }
4376
4377            final long origId = Binder.clearCallingIdentity();
4378            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4379                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4380                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4381                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4382                    false, false, null, null, null);
4383            Binder.restoreCallingIdentity(origId);
4384
4385            r.finishing = wasFinishing;
4386            if (res != ActivityManager.START_SUCCESS) {
4387                return false;
4388            }
4389            return true;
4390        }
4391    }
4392
4393    @Override
4394    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4395        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4396            String msg = "Permission Denial: startActivityFromRecents called without " +
4397                    START_TASKS_FROM_RECENTS;
4398            Slog.w(TAG, msg);
4399            throw new SecurityException(msg);
4400        }
4401        final long origId = Binder.clearCallingIdentity();
4402        try {
4403            return startActivityFromRecentsInner(taskId, bOptions);
4404        } finally {
4405            Binder.restoreCallingIdentity(origId);
4406        }
4407    }
4408
4409    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4410        final TaskRecord task;
4411        final int callingUid;
4412        final String callingPackage;
4413        final Intent intent;
4414        final int userId;
4415        synchronized (this) {
4416            final ActivityOptions activityOptions = (bOptions != null)
4417                    ? new ActivityOptions(bOptions) : null;
4418            final int launchStackId = (activityOptions != null)
4419                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4420
4421            if (launchStackId == HOME_STACK_ID) {
4422                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4423                        + taskId + " can't be launch in the home stack.");
4424            }
4425            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4426            if (task == null) {
4427                throw new IllegalArgumentException(
4428                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4429            }
4430
4431            if (launchStackId != INVALID_STACK_ID) {
4432                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4433                    mWindowManager.setDockedStackCreateState(
4434                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4435                }
4436                if (task.stack.mStackId != launchStackId) {
4437                    mStackSupervisor.moveTaskToStackLocked(
4438                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4439                            ANIMATE);
4440                }
4441            }
4442
4443            // If the user must confirm credentials (e.g. when first launching a work app and the
4444            // Work Challenge is present) let startActivityInPackage handle the intercepting.
4445            if (!mUserController.shouldConfirmCredentials(task.userId)
4446                    && task.getRootActivity() != null) {
4447                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4448                return ActivityManager.START_TASK_TO_FRONT;
4449            }
4450            callingUid = task.mCallingUid;
4451            callingPackage = task.mCallingPackage;
4452            intent = task.intent;
4453            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4454            userId = task.userId;
4455        }
4456        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4457                bOptions, userId, null, task);
4458    }
4459
4460    final int startActivityInPackage(int uid, String callingPackage,
4461            Intent intent, String resolvedType, IBinder resultTo,
4462            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4463            IActivityContainer container, TaskRecord inTask) {
4464
4465        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4466                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4467
4468        // TODO: Switch to user app stacks here.
4469        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4470                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4471                null, null, null, bOptions, false, userId, container, inTask);
4472        return ret;
4473    }
4474
4475    @Override
4476    public final int startActivities(IApplicationThread caller, String callingPackage,
4477            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4478            int userId) {
4479        enforceNotIsolatedCaller("startActivities");
4480        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4481                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4482        // TODO: Switch to user app stacks here.
4483        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4484                resolvedTypes, resultTo, bOptions, userId);
4485        return ret;
4486    }
4487
4488    final int startActivitiesInPackage(int uid, String callingPackage,
4489            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4490            Bundle bOptions, int userId) {
4491
4492        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4493                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4494        // TODO: Switch to user app stacks here.
4495        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4496                resultTo, bOptions, userId);
4497        return ret;
4498    }
4499
4500    @Override
4501    public void reportActivityFullyDrawn(IBinder token) {
4502        synchronized (this) {
4503            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4504            if (r == null) {
4505                return;
4506            }
4507            r.reportFullyDrawnLocked();
4508        }
4509    }
4510
4511    @Override
4512    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4513        synchronized (this) {
4514            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4515            if (r == null) {
4516                return;
4517            }
4518            TaskRecord task = r.task;
4519            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4520                // Fixed screen orientation isn't supported when activities aren't in full screen
4521                // mode.
4522                return;
4523            }
4524            final long origId = Binder.clearCallingIdentity();
4525            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4526            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4527                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4528            if (config != null) {
4529                r.frozenBeforeDestroy = true;
4530                if (!updateConfigurationLocked(config, r, false)) {
4531                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4532                }
4533            }
4534            Binder.restoreCallingIdentity(origId);
4535        }
4536    }
4537
4538    @Override
4539    public int getRequestedOrientation(IBinder token) {
4540        synchronized (this) {
4541            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4542            if (r == null) {
4543                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4544            }
4545            return mWindowManager.getAppOrientation(r.appToken);
4546        }
4547    }
4548
4549    /**
4550     * This is the internal entry point for handling Activity.finish().
4551     *
4552     * @param token The Binder token referencing the Activity we want to finish.
4553     * @param resultCode Result code, if any, from this Activity.
4554     * @param resultData Result data (Intent), if any, from this Activity.
4555     * @param finishTask Whether to finish the task associated with this Activity.
4556     *
4557     * @return Returns true if the activity successfully finished, or false if it is still running.
4558     */
4559    @Override
4560    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4561            int finishTask) {
4562        // Refuse possible leaked file descriptors
4563        if (resultData != null && resultData.hasFileDescriptors() == true) {
4564            throw new IllegalArgumentException("File descriptors passed in Intent");
4565        }
4566
4567        synchronized(this) {
4568            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4569            if (r == null) {
4570                return true;
4571            }
4572            // Keep track of the root activity of the task before we finish it
4573            TaskRecord tr = r.task;
4574            ActivityRecord rootR = tr.getRootActivity();
4575            if (rootR == null) {
4576                Slog.w(TAG, "Finishing task with all activities already finished");
4577            }
4578            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4579            // finish.
4580            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4581                    mStackSupervisor.isLastLockedTask(tr)) {
4582                Slog.i(TAG, "Not finishing task in lock task mode");
4583                mStackSupervisor.showLockTaskToast();
4584                return false;
4585            }
4586            if (mController != null) {
4587                // Find the first activity that is not finishing.
4588                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4589                if (next != null) {
4590                    // ask watcher if this is allowed
4591                    boolean resumeOK = true;
4592                    try {
4593                        resumeOK = mController.activityResuming(next.packageName);
4594                    } catch (RemoteException e) {
4595                        mController = null;
4596                        Watchdog.getInstance().setActivityController(null);
4597                    }
4598
4599                    if (!resumeOK) {
4600                        Slog.i(TAG, "Not finishing activity because controller resumed");
4601                        return false;
4602                    }
4603                }
4604            }
4605            final long origId = Binder.clearCallingIdentity();
4606            try {
4607                boolean res;
4608                final boolean finishWithRootActivity =
4609                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4610                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4611                        || (finishWithRootActivity && r == rootR)) {
4612                    // If requested, remove the task that is associated to this activity only if it
4613                    // was the root activity in the task. The result code and data is ignored
4614                    // because we don't support returning them across task boundaries. Also, to
4615                    // keep backwards compatibility we remove the task from recents when finishing
4616                    // task with root activity.
4617                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4618                    if (!res) {
4619                        Slog.i(TAG, "Removing task failed to finish activity");
4620                    }
4621                } else {
4622                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4623                            resultData, "app-request", true);
4624                    if (!res) {
4625                        Slog.i(TAG, "Failed to finish by app-request");
4626                    }
4627                }
4628                return res;
4629            } finally {
4630                Binder.restoreCallingIdentity(origId);
4631            }
4632        }
4633    }
4634
4635    @Override
4636    public final void finishHeavyWeightApp() {
4637        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4638                != PackageManager.PERMISSION_GRANTED) {
4639            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4640                    + Binder.getCallingPid()
4641                    + ", uid=" + Binder.getCallingUid()
4642                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4643            Slog.w(TAG, msg);
4644            throw new SecurityException(msg);
4645        }
4646
4647        synchronized(this) {
4648            if (mHeavyWeightProcess == null) {
4649                return;
4650            }
4651
4652            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4653            for (int i = 0; i < activities.size(); i++) {
4654                ActivityRecord r = activities.get(i);
4655                if (!r.finishing && r.isInStackLocked()) {
4656                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4657                            null, "finish-heavy", true);
4658                }
4659            }
4660
4661            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4662                    mHeavyWeightProcess.userId, 0));
4663            mHeavyWeightProcess = null;
4664        }
4665    }
4666
4667    @Override
4668    public void crashApplication(int uid, int initialPid, String packageName,
4669            String message) {
4670        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4671                != PackageManager.PERMISSION_GRANTED) {
4672            String msg = "Permission Denial: crashApplication() from pid="
4673                    + Binder.getCallingPid()
4674                    + ", uid=" + Binder.getCallingUid()
4675                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4676            Slog.w(TAG, msg);
4677            throw new SecurityException(msg);
4678        }
4679
4680        synchronized(this) {
4681            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4682        }
4683    }
4684
4685    @Override
4686    public final void finishSubActivity(IBinder token, String resultWho,
4687            int requestCode) {
4688        synchronized(this) {
4689            final long origId = Binder.clearCallingIdentity();
4690            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4691            if (r != null) {
4692                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4693            }
4694            Binder.restoreCallingIdentity(origId);
4695        }
4696    }
4697
4698    @Override
4699    public boolean finishActivityAffinity(IBinder token) {
4700        synchronized(this) {
4701            final long origId = Binder.clearCallingIdentity();
4702            try {
4703                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4704                if (r == null) {
4705                    return false;
4706                }
4707
4708                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4709                // can finish.
4710                final TaskRecord task = r.task;
4711                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4712                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4713                    mStackSupervisor.showLockTaskToast();
4714                    return false;
4715                }
4716                return task.stack.finishActivityAffinityLocked(r);
4717            } finally {
4718                Binder.restoreCallingIdentity(origId);
4719            }
4720        }
4721    }
4722
4723    @Override
4724    public void finishVoiceTask(IVoiceInteractionSession session) {
4725        synchronized (this) {
4726            final long origId = Binder.clearCallingIdentity();
4727            try {
4728                // TODO: VI Consider treating local voice interactions and voice tasks
4729                // differently here
4730                mStackSupervisor.finishVoiceTask(session);
4731            } finally {
4732                Binder.restoreCallingIdentity(origId);
4733            }
4734        }
4735
4736    }
4737
4738    @Override
4739    public boolean releaseActivityInstance(IBinder token) {
4740        synchronized(this) {
4741            final long origId = Binder.clearCallingIdentity();
4742            try {
4743                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4744                if (r == null) {
4745                    return false;
4746                }
4747                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4748            } finally {
4749                Binder.restoreCallingIdentity(origId);
4750            }
4751        }
4752    }
4753
4754    @Override
4755    public void releaseSomeActivities(IApplicationThread appInt) {
4756        synchronized(this) {
4757            final long origId = Binder.clearCallingIdentity();
4758            try {
4759                ProcessRecord app = getRecordForAppLocked(appInt);
4760                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4761            } finally {
4762                Binder.restoreCallingIdentity(origId);
4763            }
4764        }
4765    }
4766
4767    @Override
4768    public boolean willActivityBeVisible(IBinder token) {
4769        synchronized(this) {
4770            ActivityStack stack = ActivityRecord.getStackLocked(token);
4771            if (stack != null) {
4772                return stack.willActivityBeVisibleLocked(token);
4773            }
4774            return false;
4775        }
4776    }
4777
4778    @Override
4779    public void overridePendingTransition(IBinder token, String packageName,
4780            int enterAnim, int exitAnim) {
4781        synchronized(this) {
4782            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4783            if (self == null) {
4784                return;
4785            }
4786
4787            final long origId = Binder.clearCallingIdentity();
4788
4789            if (self.state == ActivityState.RESUMED
4790                    || self.state == ActivityState.PAUSING) {
4791                mWindowManager.overridePendingAppTransition(packageName,
4792                        enterAnim, exitAnim, null);
4793            }
4794
4795            Binder.restoreCallingIdentity(origId);
4796        }
4797    }
4798
4799    /**
4800     * Main function for removing an existing process from the activity manager
4801     * as a result of that process going away.  Clears out all connections
4802     * to the process.
4803     */
4804    private final void handleAppDiedLocked(ProcessRecord app,
4805            boolean restarting, boolean allowRestart) {
4806        int pid = app.pid;
4807        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4808        if (!kept && !restarting) {
4809            removeLruProcessLocked(app);
4810            if (pid > 0) {
4811                ProcessList.remove(pid);
4812            }
4813        }
4814
4815        if (mProfileProc == app) {
4816            clearProfilerLocked();
4817        }
4818
4819        // Remove this application's activities from active lists.
4820        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4821
4822        app.activities.clear();
4823
4824        if (app.instrumentationClass != null) {
4825            Slog.w(TAG, "Crash of app " + app.processName
4826                  + " running instrumentation " + app.instrumentationClass);
4827            Bundle info = new Bundle();
4828            info.putString("shortMsg", "Process crashed.");
4829            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4830        }
4831
4832        if (!restarting && hasVisibleActivities
4833                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4834            // If there was nothing to resume, and we are not already restarting this process, but
4835            // there is a visible activity that is hosted by the process...  then make sure all
4836            // visible activities are running, taking care of restarting this process.
4837            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4838        }
4839    }
4840
4841    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4842        IBinder threadBinder = thread.asBinder();
4843        // Find the application record.
4844        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4845            ProcessRecord rec = mLruProcesses.get(i);
4846            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4847                return i;
4848            }
4849        }
4850        return -1;
4851    }
4852
4853    final ProcessRecord getRecordForAppLocked(
4854            IApplicationThread thread) {
4855        if (thread == null) {
4856            return null;
4857        }
4858
4859        int appIndex = getLRURecordIndexForAppLocked(thread);
4860        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4861    }
4862
4863    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4864        // If there are no longer any background processes running,
4865        // and the app that died was not running instrumentation,
4866        // then tell everyone we are now low on memory.
4867        boolean haveBg = false;
4868        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4869            ProcessRecord rec = mLruProcesses.get(i);
4870            if (rec.thread != null
4871                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4872                haveBg = true;
4873                break;
4874            }
4875        }
4876
4877        if (!haveBg) {
4878            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4879            if (doReport) {
4880                long now = SystemClock.uptimeMillis();
4881                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4882                    doReport = false;
4883                } else {
4884                    mLastMemUsageReportTime = now;
4885                }
4886            }
4887            final ArrayList<ProcessMemInfo> memInfos
4888                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4889            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4890            long now = SystemClock.uptimeMillis();
4891            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4892                ProcessRecord rec = mLruProcesses.get(i);
4893                if (rec == dyingProc || rec.thread == null) {
4894                    continue;
4895                }
4896                if (doReport) {
4897                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4898                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4899                }
4900                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4901                    // The low memory report is overriding any current
4902                    // state for a GC request.  Make sure to do
4903                    // heavy/important/visible/foreground processes first.
4904                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4905                        rec.lastRequestedGc = 0;
4906                    } else {
4907                        rec.lastRequestedGc = rec.lastLowMemory;
4908                    }
4909                    rec.reportLowMemory = true;
4910                    rec.lastLowMemory = now;
4911                    mProcessesToGc.remove(rec);
4912                    addProcessToGcListLocked(rec);
4913                }
4914            }
4915            if (doReport) {
4916                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4917                mHandler.sendMessage(msg);
4918            }
4919            scheduleAppGcsLocked();
4920        }
4921    }
4922
4923    final void appDiedLocked(ProcessRecord app) {
4924       appDiedLocked(app, app.pid, app.thread, false);
4925    }
4926
4927    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4928            boolean fromBinderDied) {
4929        // First check if this ProcessRecord is actually active for the pid.
4930        synchronized (mPidsSelfLocked) {
4931            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4932            if (curProc != app) {
4933                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4934                return;
4935            }
4936        }
4937
4938        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4939        synchronized (stats) {
4940            stats.noteProcessDiedLocked(app.info.uid, pid);
4941        }
4942
4943        if (!app.killed) {
4944            if (!fromBinderDied) {
4945                Process.killProcessQuiet(pid);
4946            }
4947            killProcessGroup(app.info.uid, pid);
4948            app.killed = true;
4949        }
4950
4951        // Clean up already done if the process has been re-started.
4952        if (app.pid == pid && app.thread != null &&
4953                app.thread.asBinder() == thread.asBinder()) {
4954            boolean doLowMem = app.instrumentationClass == null;
4955            boolean doOomAdj = doLowMem;
4956            if (!app.killedByAm) {
4957                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4958                        + ") has died");
4959                mAllowLowerMemLevel = true;
4960            } else {
4961                // Note that we always want to do oom adj to update our state with the
4962                // new number of procs.
4963                mAllowLowerMemLevel = false;
4964                doLowMem = false;
4965            }
4966            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4967            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4968                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4969            handleAppDiedLocked(app, false, true);
4970
4971            if (doOomAdj) {
4972                updateOomAdjLocked();
4973            }
4974            if (doLowMem) {
4975                doLowMemReportIfNeededLocked(app);
4976            }
4977        } else if (app.pid != pid) {
4978            // A new process has already been started.
4979            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4980                    + ") has died and restarted (pid " + app.pid + ").");
4981            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4982        } else if (DEBUG_PROCESSES) {
4983            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4984                    + thread.asBinder());
4985        }
4986    }
4987
4988    /**
4989     * If a stack trace dump file is configured, dump process stack traces.
4990     * @param clearTraces causes the dump file to be erased prior to the new
4991     *    traces being written, if true; when false, the new traces will be
4992     *    appended to any existing file content.
4993     * @param firstPids of dalvik VM processes to dump stack traces for first
4994     * @param lastPids of dalvik VM processes to dump stack traces for last
4995     * @param nativeProcs optional list of native process names to dump stack crawls
4996     * @return file containing stack traces, or null if no dump file is configured
4997     */
4998    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4999            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5000        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5001        if (tracesPath == null || tracesPath.length() == 0) {
5002            return null;
5003        }
5004
5005        File tracesFile = new File(tracesPath);
5006        try {
5007            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5008            tracesFile.createNewFile();
5009            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5010        } catch (IOException e) {
5011            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5012            return null;
5013        }
5014
5015        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5016        return tracesFile;
5017    }
5018
5019    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5020            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5021        // Use a FileObserver to detect when traces finish writing.
5022        // The order of traces is considered important to maintain for legibility.
5023        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5024            @Override
5025            public synchronized void onEvent(int event, String path) { notify(); }
5026        };
5027
5028        try {
5029            observer.startWatching();
5030
5031            // First collect all of the stacks of the most important pids.
5032            if (firstPids != null) {
5033                try {
5034                    int num = firstPids.size();
5035                    for (int i = 0; i < num; i++) {
5036                        synchronized (observer) {
5037                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5038                            observer.wait(200);  // Wait for write-close, give up after 200msec
5039                        }
5040                    }
5041                } catch (InterruptedException e) {
5042                    Slog.wtf(TAG, e);
5043                }
5044            }
5045
5046            // Next collect the stacks of the native pids
5047            if (nativeProcs != null) {
5048                int[] pids = Process.getPidsForCommands(nativeProcs);
5049                if (pids != null) {
5050                    for (int pid : pids) {
5051                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5052                    }
5053                }
5054            }
5055
5056            // Lastly, measure CPU usage.
5057            if (processCpuTracker != null) {
5058                processCpuTracker.init();
5059                System.gc();
5060                processCpuTracker.update();
5061                try {
5062                    synchronized (processCpuTracker) {
5063                        processCpuTracker.wait(500); // measure over 1/2 second.
5064                    }
5065                } catch (InterruptedException e) {
5066                }
5067                processCpuTracker.update();
5068
5069                // We'll take the stack crawls of just the top apps using CPU.
5070                final int N = processCpuTracker.countWorkingStats();
5071                int numProcs = 0;
5072                for (int i=0; i<N && numProcs<5; i++) {
5073                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5074                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5075                        numProcs++;
5076                        try {
5077                            synchronized (observer) {
5078                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5079                                observer.wait(200);  // Wait for write-close, give up after 200msec
5080                            }
5081                        } catch (InterruptedException e) {
5082                            Slog.wtf(TAG, e);
5083                        }
5084
5085                    }
5086                }
5087            }
5088        } finally {
5089            observer.stopWatching();
5090        }
5091    }
5092
5093    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5094        if (true || IS_USER_BUILD) {
5095            return;
5096        }
5097        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5098        if (tracesPath == null || tracesPath.length() == 0) {
5099            return;
5100        }
5101
5102        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5103        StrictMode.allowThreadDiskWrites();
5104        try {
5105            final File tracesFile = new File(tracesPath);
5106            final File tracesDir = tracesFile.getParentFile();
5107            final File tracesTmp = new File(tracesDir, "__tmp__");
5108            try {
5109                if (tracesFile.exists()) {
5110                    tracesTmp.delete();
5111                    tracesFile.renameTo(tracesTmp);
5112                }
5113                StringBuilder sb = new StringBuilder();
5114                Time tobj = new Time();
5115                tobj.set(System.currentTimeMillis());
5116                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5117                sb.append(": ");
5118                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5119                sb.append(" since ");
5120                sb.append(msg);
5121                FileOutputStream fos = new FileOutputStream(tracesFile);
5122                fos.write(sb.toString().getBytes());
5123                if (app == null) {
5124                    fos.write("\n*** No application process!".getBytes());
5125                }
5126                fos.close();
5127                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5128            } catch (IOException e) {
5129                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5130                return;
5131            }
5132
5133            if (app != null) {
5134                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5135                firstPids.add(app.pid);
5136                dumpStackTraces(tracesPath, firstPids, null, null, null);
5137            }
5138
5139            File lastTracesFile = null;
5140            File curTracesFile = null;
5141            for (int i=9; i>=0; i--) {
5142                String name = String.format(Locale.US, "slow%02d.txt", i);
5143                curTracesFile = new File(tracesDir, name);
5144                if (curTracesFile.exists()) {
5145                    if (lastTracesFile != null) {
5146                        curTracesFile.renameTo(lastTracesFile);
5147                    } else {
5148                        curTracesFile.delete();
5149                    }
5150                }
5151                lastTracesFile = curTracesFile;
5152            }
5153            tracesFile.renameTo(curTracesFile);
5154            if (tracesTmp.exists()) {
5155                tracesTmp.renameTo(tracesFile);
5156            }
5157        } finally {
5158            StrictMode.setThreadPolicy(oldPolicy);
5159        }
5160    }
5161
5162    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5163        if (!mLaunchWarningShown) {
5164            mLaunchWarningShown = true;
5165            mUiHandler.post(new Runnable() {
5166                @Override
5167                public void run() {
5168                    synchronized (ActivityManagerService.this) {
5169                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5170                        d.show();
5171                        mUiHandler.postDelayed(new Runnable() {
5172                            @Override
5173                            public void run() {
5174                                synchronized (ActivityManagerService.this) {
5175                                    d.dismiss();
5176                                    mLaunchWarningShown = false;
5177                                }
5178                            }
5179                        }, 4000);
5180                    }
5181                }
5182            });
5183        }
5184    }
5185
5186    @Override
5187    public boolean clearApplicationUserData(final String packageName,
5188            final IPackageDataObserver observer, int userId) {
5189        enforceNotIsolatedCaller("clearApplicationUserData");
5190        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5191            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5192        }
5193        int uid = Binder.getCallingUid();
5194        int pid = Binder.getCallingPid();
5195        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5196                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5197        long callingId = Binder.clearCallingIdentity();
5198        try {
5199            IPackageManager pm = AppGlobals.getPackageManager();
5200            int pkgUid = -1;
5201            synchronized(this) {
5202                try {
5203                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5204                } catch (RemoteException e) {
5205                }
5206                if (pkgUid == -1) {
5207                    Slog.w(TAG, "Invalid packageName: " + packageName);
5208                    if (observer != null) {
5209                        try {
5210                            observer.onRemoveCompleted(packageName, false);
5211                        } catch (RemoteException e) {
5212                            Slog.i(TAG, "Observer no longer exists.");
5213                        }
5214                    }
5215                    return false;
5216                }
5217                if (uid == pkgUid || checkComponentPermission(
5218                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5219                        pid, uid, -1, true)
5220                        == PackageManager.PERMISSION_GRANTED) {
5221                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5222                } else {
5223                    throw new SecurityException("PID " + pid + " does not have permission "
5224                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5225                                    + " of package " + packageName);
5226                }
5227
5228                // Remove all tasks match the cleared application package and user
5229                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5230                    final TaskRecord tr = mRecentTasks.get(i);
5231                    final String taskPackageName =
5232                            tr.getBaseIntent().getComponent().getPackageName();
5233                    if (tr.userId != userId) continue;
5234                    if (!taskPackageName.equals(packageName)) continue;
5235                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5236                }
5237            }
5238
5239            try {
5240                // Clear application user data
5241                pm.clearApplicationUserData(packageName, observer, userId);
5242
5243                synchronized(this) {
5244                    // Remove all permissions granted from/to this package
5245                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5246                }
5247
5248                // Remove all zen rules created by this package; revoke it's zen access.
5249                INotificationManager inm = NotificationManager.getService();
5250                inm.removeAutomaticZenRules(packageName);
5251                inm.setNotificationPolicyAccessGranted(packageName, false);
5252
5253                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5254                        Uri.fromParts("package", packageName, null));
5255                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5256                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5257                        null, null, 0, null, null, null, null, false, false, userId);
5258            } catch (RemoteException e) {
5259            }
5260        } finally {
5261            Binder.restoreCallingIdentity(callingId);
5262        }
5263        return true;
5264    }
5265
5266    @Override
5267    public void killBackgroundProcesses(final String packageName, int userId) {
5268        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5269                != PackageManager.PERMISSION_GRANTED &&
5270                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5271                        != PackageManager.PERMISSION_GRANTED) {
5272            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5273                    + Binder.getCallingPid()
5274                    + ", uid=" + Binder.getCallingUid()
5275                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5276            Slog.w(TAG, msg);
5277            throw new SecurityException(msg);
5278        }
5279
5280        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5281                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5282        long callingId = Binder.clearCallingIdentity();
5283        try {
5284            IPackageManager pm = AppGlobals.getPackageManager();
5285            synchronized(this) {
5286                int appId = -1;
5287                try {
5288                    appId = UserHandle.getAppId(
5289                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5290                } catch (RemoteException e) {
5291                }
5292                if (appId == -1) {
5293                    Slog.w(TAG, "Invalid packageName: " + packageName);
5294                    return;
5295                }
5296                killPackageProcessesLocked(packageName, appId, userId,
5297                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5298            }
5299        } finally {
5300            Binder.restoreCallingIdentity(callingId);
5301        }
5302    }
5303
5304    @Override
5305    public void killAllBackgroundProcesses() {
5306        killAllBackgroundProcesses(-1);
5307    }
5308
5309    /**
5310     * Kills all background processes with targetSdkVersion below the specified
5311     * target SDK version.
5312     *
5313     * @param targetSdkVersion the target SDK version below which to kill
5314     *                         processes, or {@code -1} to kill all processes
5315     */
5316    private void killAllBackgroundProcesses(int targetSdkVersion) {
5317        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5318                != PackageManager.PERMISSION_GRANTED) {
5319            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5320                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5321                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5322            Slog.w(TAG, msg);
5323            throw new SecurityException(msg);
5324        }
5325
5326        final long callingId = Binder.clearCallingIdentity();
5327        try {
5328            synchronized (this) {
5329                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5330                final int NP = mProcessNames.getMap().size();
5331                for (int ip = 0; ip < NP; ip++) {
5332                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5333                    final int NA = apps.size();
5334                    for (int ia = 0; ia < NA; ia++) {
5335                        final ProcessRecord app = apps.valueAt(ia);
5336                        if (app.persistent) {
5337                            // We don't kill persistent processes.
5338                            continue;
5339                        }
5340                        if (targetSdkVersion > 0 && app.info.targetSdkVersion < targetSdkVersion) {
5341                            continue;
5342                        }
5343                        if (app.removed) {
5344                            procs.add(app);
5345                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5346                            app.removed = true;
5347                            procs.add(app);
5348                        }
5349                    }
5350                }
5351
5352                final int N = procs.size();
5353                for (int i = 0; i < N; i++) {
5354                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5355                }
5356
5357                mAllowLowerMemLevel = true;
5358
5359                updateOomAdjLocked();
5360                doLowMemReportIfNeededLocked(null);
5361            }
5362        } finally {
5363            Binder.restoreCallingIdentity(callingId);
5364        }
5365    }
5366
5367    @Override
5368    public void forceStopPackage(final String packageName, int userId) {
5369        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5370                != PackageManager.PERMISSION_GRANTED) {
5371            String msg = "Permission Denial: forceStopPackage() from pid="
5372                    + Binder.getCallingPid()
5373                    + ", uid=" + Binder.getCallingUid()
5374                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5375            Slog.w(TAG, msg);
5376            throw new SecurityException(msg);
5377        }
5378        final int callingPid = Binder.getCallingPid();
5379        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5380                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5381        long callingId = Binder.clearCallingIdentity();
5382        try {
5383            IPackageManager pm = AppGlobals.getPackageManager();
5384            synchronized(this) {
5385                int[] users = userId == UserHandle.USER_ALL
5386                        ? mUserController.getUsers() : new int[] { userId };
5387                for (int user : users) {
5388                    int pkgUid = -1;
5389                    try {
5390                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5391                                user);
5392                    } catch (RemoteException e) {
5393                    }
5394                    if (pkgUid == -1) {
5395                        Slog.w(TAG, "Invalid packageName: " + packageName);
5396                        continue;
5397                    }
5398                    try {
5399                        pm.setPackageStoppedState(packageName, true, user);
5400                    } catch (RemoteException e) {
5401                    } catch (IllegalArgumentException e) {
5402                        Slog.w(TAG, "Failed trying to unstop package "
5403                                + packageName + ": " + e);
5404                    }
5405                    if (mUserController.isUserRunningLocked(user, 0)) {
5406                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5407                    }
5408                }
5409            }
5410        } finally {
5411            Binder.restoreCallingIdentity(callingId);
5412        }
5413    }
5414
5415    @Override
5416    public void addPackageDependency(String packageName) {
5417        synchronized (this) {
5418            int callingPid = Binder.getCallingPid();
5419            if (callingPid == Process.myPid()) {
5420                //  Yeah, um, no.
5421                return;
5422            }
5423            ProcessRecord proc;
5424            synchronized (mPidsSelfLocked) {
5425                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5426            }
5427            if (proc != null) {
5428                if (proc.pkgDeps == null) {
5429                    proc.pkgDeps = new ArraySet<String>(1);
5430                }
5431                proc.pkgDeps.add(packageName);
5432            }
5433        }
5434    }
5435
5436    /*
5437     * The pkg name and app id have to be specified.
5438     */
5439    @Override
5440    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5441        if (pkg == null) {
5442            return;
5443        }
5444        // Make sure the uid is valid.
5445        if (appid < 0) {
5446            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5447            return;
5448        }
5449        int callerUid = Binder.getCallingUid();
5450        // Only the system server can kill an application
5451        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5452            // Post an aysnc message to kill the application
5453            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5454            msg.arg1 = appid;
5455            msg.arg2 = 0;
5456            Bundle bundle = new Bundle();
5457            bundle.putString("pkg", pkg);
5458            bundle.putString("reason", reason);
5459            msg.obj = bundle;
5460            mHandler.sendMessage(msg);
5461        } else {
5462            throw new SecurityException(callerUid + " cannot kill pkg: " +
5463                    pkg);
5464        }
5465    }
5466
5467    @Override
5468    public void closeSystemDialogs(String reason) {
5469        enforceNotIsolatedCaller("closeSystemDialogs");
5470
5471        final int pid = Binder.getCallingPid();
5472        final int uid = Binder.getCallingUid();
5473        final long origId = Binder.clearCallingIdentity();
5474        try {
5475            synchronized (this) {
5476                // Only allow this from foreground processes, so that background
5477                // applications can't abuse it to prevent system UI from being shown.
5478                if (uid >= Process.FIRST_APPLICATION_UID) {
5479                    ProcessRecord proc;
5480                    synchronized (mPidsSelfLocked) {
5481                        proc = mPidsSelfLocked.get(pid);
5482                    }
5483                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5484                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5485                                + " from background process " + proc);
5486                        return;
5487                    }
5488                }
5489                closeSystemDialogsLocked(reason);
5490            }
5491        } finally {
5492            Binder.restoreCallingIdentity(origId);
5493        }
5494    }
5495
5496    void closeSystemDialogsLocked(String reason) {
5497        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5498        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5499                | Intent.FLAG_RECEIVER_FOREGROUND);
5500        if (reason != null) {
5501            intent.putExtra("reason", reason);
5502        }
5503        mWindowManager.closeSystemDialogs(reason);
5504
5505        mStackSupervisor.closeSystemDialogsLocked();
5506
5507        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5508                AppOpsManager.OP_NONE, null, false, false,
5509                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5510    }
5511
5512    @Override
5513    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5514        enforceNotIsolatedCaller("getProcessMemoryInfo");
5515        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5516        for (int i=pids.length-1; i>=0; i--) {
5517            ProcessRecord proc;
5518            int oomAdj;
5519            synchronized (this) {
5520                synchronized (mPidsSelfLocked) {
5521                    proc = mPidsSelfLocked.get(pids[i]);
5522                    oomAdj = proc != null ? proc.setAdj : 0;
5523                }
5524            }
5525            infos[i] = new Debug.MemoryInfo();
5526            Debug.getMemoryInfo(pids[i], infos[i]);
5527            if (proc != null) {
5528                synchronized (this) {
5529                    if (proc.thread != null && proc.setAdj == oomAdj) {
5530                        // Record this for posterity if the process has been stable.
5531                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5532                                infos[i].getTotalUss(), false, proc.pkgList);
5533                    }
5534                }
5535            }
5536        }
5537        return infos;
5538    }
5539
5540    @Override
5541    public long[] getProcessPss(int[] pids) {
5542        enforceNotIsolatedCaller("getProcessPss");
5543        long[] pss = new long[pids.length];
5544        for (int i=pids.length-1; i>=0; i--) {
5545            ProcessRecord proc;
5546            int oomAdj;
5547            synchronized (this) {
5548                synchronized (mPidsSelfLocked) {
5549                    proc = mPidsSelfLocked.get(pids[i]);
5550                    oomAdj = proc != null ? proc.setAdj : 0;
5551                }
5552            }
5553            long[] tmpUss = new long[1];
5554            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5555            if (proc != null) {
5556                synchronized (this) {
5557                    if (proc.thread != null && proc.setAdj == oomAdj) {
5558                        // Record this for posterity if the process has been stable.
5559                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5560                    }
5561                }
5562            }
5563        }
5564        return pss;
5565    }
5566
5567    @Override
5568    public void killApplicationProcess(String processName, int uid) {
5569        if (processName == null) {
5570            return;
5571        }
5572
5573        int callerUid = Binder.getCallingUid();
5574        // Only the system server can kill an application
5575        if (callerUid == Process.SYSTEM_UID) {
5576            synchronized (this) {
5577                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5578                if (app != null && app.thread != null) {
5579                    try {
5580                        app.thread.scheduleSuicide();
5581                    } catch (RemoteException e) {
5582                        // If the other end already died, then our work here is done.
5583                    }
5584                } else {
5585                    Slog.w(TAG, "Process/uid not found attempting kill of "
5586                            + processName + " / " + uid);
5587                }
5588            }
5589        } else {
5590            throw new SecurityException(callerUid + " cannot kill app process: " +
5591                    processName);
5592        }
5593    }
5594
5595    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5596        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5597                false, true, false, false, UserHandle.getUserId(uid), reason);
5598        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5599                Uri.fromParts("package", packageName, null));
5600        if (!mProcessesReady) {
5601            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5602                    | Intent.FLAG_RECEIVER_FOREGROUND);
5603        }
5604        intent.putExtra(Intent.EXTRA_UID, uid);
5605        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5606        broadcastIntentLocked(null, null, intent,
5607                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5608                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5609    }
5610
5611
5612    private final boolean killPackageProcessesLocked(String packageName, int appId,
5613            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5614            boolean doit, boolean evenPersistent, String reason) {
5615        ArrayList<ProcessRecord> procs = new ArrayList<>();
5616
5617        // Remove all processes this package may have touched: all with the
5618        // same UID (except for the system or root user), and all whose name
5619        // matches the package name.
5620        final int NP = mProcessNames.getMap().size();
5621        for (int ip=0; ip<NP; ip++) {
5622            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5623            final int NA = apps.size();
5624            for (int ia=0; ia<NA; ia++) {
5625                ProcessRecord app = apps.valueAt(ia);
5626                if (app.persistent && !evenPersistent) {
5627                    // we don't kill persistent processes
5628                    continue;
5629                }
5630                if (app.removed) {
5631                    if (doit) {
5632                        procs.add(app);
5633                    }
5634                    continue;
5635                }
5636
5637                // Skip process if it doesn't meet our oom adj requirement.
5638                if (app.setAdj < minOomAdj) {
5639                    continue;
5640                }
5641
5642                // If no package is specified, we call all processes under the
5643                // give user id.
5644                if (packageName == null) {
5645                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5646                        continue;
5647                    }
5648                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5649                        continue;
5650                    }
5651                // Package has been specified, we want to hit all processes
5652                // that match it.  We need to qualify this by the processes
5653                // that are running under the specified app and user ID.
5654                } else {
5655                    final boolean isDep = app.pkgDeps != null
5656                            && app.pkgDeps.contains(packageName);
5657                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5658                        continue;
5659                    }
5660                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5661                        continue;
5662                    }
5663                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5664                        continue;
5665                    }
5666                }
5667
5668                // Process has passed all conditions, kill it!
5669                if (!doit) {
5670                    return true;
5671                }
5672                app.removed = true;
5673                procs.add(app);
5674            }
5675        }
5676
5677        int N = procs.size();
5678        for (int i=0; i<N; i++) {
5679            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5680        }
5681        updateOomAdjLocked();
5682        return N > 0;
5683    }
5684
5685    private void cleanupDisabledPackageComponentsLocked(
5686            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5687
5688        Set<String> disabledClasses = null;
5689        boolean packageDisabled = false;
5690        IPackageManager pm = AppGlobals.getPackageManager();
5691
5692        if (changedClasses == null) {
5693            // Nothing changed...
5694            return;
5695        }
5696
5697        // Determine enable/disable state of the package and its components.
5698        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5699        for (int i = changedClasses.length - 1; i >= 0; i--) {
5700            final String changedClass = changedClasses[i];
5701
5702            if (changedClass.equals(packageName)) {
5703                try {
5704                    // Entire package setting changed
5705                    enabled = pm.getApplicationEnabledSetting(packageName,
5706                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5707                } catch (Exception e) {
5708                    // No such package/component; probably racing with uninstall.  In any
5709                    // event it means we have nothing further to do here.
5710                    return;
5711                }
5712                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5713                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5714                if (packageDisabled) {
5715                    // Entire package is disabled.
5716                    // No need to continue to check component states.
5717                    disabledClasses = null;
5718                    break;
5719                }
5720            } else {
5721                try {
5722                    enabled = pm.getComponentEnabledSetting(
5723                            new ComponentName(packageName, changedClass),
5724                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5725                } catch (Exception e) {
5726                    // As above, probably racing with uninstall.
5727                    return;
5728                }
5729                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5730                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5731                    if (disabledClasses == null) {
5732                        disabledClasses = new ArraySet<>(changedClasses.length);
5733                    }
5734                    disabledClasses.add(changedClass);
5735                }
5736            }
5737        }
5738
5739        if (!packageDisabled && disabledClasses == null) {
5740            // Nothing to do here...
5741            return;
5742        }
5743
5744        // Clean-up disabled activities.
5745        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5746                packageName, disabledClasses, true, false, userId) && mBooted) {
5747            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5748            mStackSupervisor.scheduleIdleLocked();
5749        }
5750
5751        // Clean-up disabled tasks
5752        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5753
5754        // Clean-up disabled services.
5755        mServices.bringDownDisabledPackageServicesLocked(
5756                packageName, disabledClasses, userId, false, killProcess, true);
5757
5758        // Clean-up disabled providers.
5759        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5760        mProviderMap.collectPackageProvidersLocked(
5761                packageName, disabledClasses, true, false, userId, providers);
5762        for (int i = providers.size() - 1; i >= 0; i--) {
5763            removeDyingProviderLocked(null, providers.get(i), true);
5764        }
5765
5766        // Clean-up disabled broadcast receivers.
5767        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5768            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5769                    packageName, disabledClasses, userId, true);
5770        }
5771
5772    }
5773
5774    final boolean forceStopPackageLocked(String packageName, int appId,
5775            boolean callerWillRestart, boolean purgeCache, boolean doit,
5776            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5777        int i;
5778
5779        if (userId == UserHandle.USER_ALL && packageName == null) {
5780            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5781        }
5782
5783        if (appId < 0 && packageName != null) {
5784            try {
5785                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5786                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5787            } catch (RemoteException e) {
5788            }
5789        }
5790
5791        if (doit) {
5792            if (packageName != null) {
5793                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5794                        + " user=" + userId + ": " + reason);
5795            } else {
5796                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5797            }
5798
5799            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5800        }
5801
5802        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5803                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5804                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5805
5806        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5807                packageName, null, doit, evenPersistent, userId)) {
5808            if (!doit) {
5809                return true;
5810            }
5811            didSomething = true;
5812        }
5813
5814        if (mServices.bringDownDisabledPackageServicesLocked(
5815                packageName, null, userId, evenPersistent, true, doit)) {
5816            if (!doit) {
5817                return true;
5818            }
5819            didSomething = true;
5820        }
5821
5822        if (packageName == null) {
5823            // Remove all sticky broadcasts from this user.
5824            mStickyBroadcasts.remove(userId);
5825        }
5826
5827        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5828        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5829                userId, providers)) {
5830            if (!doit) {
5831                return true;
5832            }
5833            didSomething = true;
5834        }
5835        for (i = providers.size() - 1; i >= 0; i--) {
5836            removeDyingProviderLocked(null, providers.get(i), true);
5837        }
5838
5839        // Remove transient permissions granted from/to this package/user
5840        removeUriPermissionsForPackageLocked(packageName, userId, false);
5841
5842        if (doit) {
5843            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5844                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5845                        packageName, null, userId, doit);
5846            }
5847        }
5848
5849        if (packageName == null || uninstalling) {
5850            // Remove pending intents.  For now we only do this when force
5851            // stopping users, because we have some problems when doing this
5852            // for packages -- app widgets are not currently cleaned up for
5853            // such packages, so they can be left with bad pending intents.
5854            if (mIntentSenderRecords.size() > 0) {
5855                Iterator<WeakReference<PendingIntentRecord>> it
5856                        = mIntentSenderRecords.values().iterator();
5857                while (it.hasNext()) {
5858                    WeakReference<PendingIntentRecord> wpir = it.next();
5859                    if (wpir == null) {
5860                        it.remove();
5861                        continue;
5862                    }
5863                    PendingIntentRecord pir = wpir.get();
5864                    if (pir == null) {
5865                        it.remove();
5866                        continue;
5867                    }
5868                    if (packageName == null) {
5869                        // Stopping user, remove all objects for the user.
5870                        if (pir.key.userId != userId) {
5871                            // Not the same user, skip it.
5872                            continue;
5873                        }
5874                    } else {
5875                        if (UserHandle.getAppId(pir.uid) != appId) {
5876                            // Different app id, skip it.
5877                            continue;
5878                        }
5879                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5880                            // Different user, skip it.
5881                            continue;
5882                        }
5883                        if (!pir.key.packageName.equals(packageName)) {
5884                            // Different package, skip it.
5885                            continue;
5886                        }
5887                    }
5888                    if (!doit) {
5889                        return true;
5890                    }
5891                    didSomething = true;
5892                    it.remove();
5893                    pir.canceled = true;
5894                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5895                        pir.key.activity.pendingResults.remove(pir.ref);
5896                    }
5897                }
5898            }
5899        }
5900
5901        if (doit) {
5902            if (purgeCache && packageName != null) {
5903                AttributeCache ac = AttributeCache.instance();
5904                if (ac != null) {
5905                    ac.removePackage(packageName);
5906                }
5907            }
5908            if (mBooted) {
5909                mStackSupervisor.resumeFocusedStackTopActivityLocked();
5910                mStackSupervisor.scheduleIdleLocked();
5911            }
5912        }
5913
5914        return didSomething;
5915    }
5916
5917    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5918        ProcessRecord old = mProcessNames.remove(name, uid);
5919        if (old != null) {
5920            old.uidRecord.numProcs--;
5921            if (old.uidRecord.numProcs == 0) {
5922                // No more processes using this uid, tell clients it is gone.
5923                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5924                        "No more processes in " + old.uidRecord);
5925                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
5926                mActiveUids.remove(uid);
5927                mBatteryStatsService.noteUidProcessState(uid,
5928                        ActivityManager.PROCESS_STATE_NONEXISTENT);
5929            }
5930            old.uidRecord = null;
5931        }
5932        mIsolatedProcesses.remove(uid);
5933        return old;
5934    }
5935
5936    private final void addProcessNameLocked(ProcessRecord proc) {
5937        // We shouldn't already have a process under this name, but just in case we
5938        // need to clean up whatever may be there now.
5939        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5940        if (old == proc && proc.persistent) {
5941            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5942            Slog.w(TAG, "Re-adding persistent process " + proc);
5943        } else if (old != null) {
5944            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5945        }
5946        UidRecord uidRec = mActiveUids.get(proc.uid);
5947        if (uidRec == null) {
5948            uidRec = new UidRecord(proc.uid);
5949            // This is the first appearance of the uid, report it now!
5950            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5951                    "Creating new process uid: " + uidRec);
5952            mActiveUids.put(proc.uid, uidRec);
5953            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
5954            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
5955        }
5956        proc.uidRecord = uidRec;
5957        uidRec.numProcs++;
5958        mProcessNames.put(proc.processName, proc.uid, proc);
5959        if (proc.isolated) {
5960            mIsolatedProcesses.put(proc.uid, proc);
5961        }
5962    }
5963
5964    boolean removeProcessLocked(ProcessRecord app,
5965            boolean callerWillRestart, boolean allowRestart, String reason) {
5966        final String name = app.processName;
5967        final int uid = app.uid;
5968        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5969            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5970
5971        removeProcessNameLocked(name, uid);
5972        if (mHeavyWeightProcess == app) {
5973            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5974                    mHeavyWeightProcess.userId, 0));
5975            mHeavyWeightProcess = null;
5976        }
5977        boolean needRestart = false;
5978        if (app.pid > 0 && app.pid != MY_PID) {
5979            int pid = app.pid;
5980            synchronized (mPidsSelfLocked) {
5981                mPidsSelfLocked.remove(pid);
5982                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5983            }
5984            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5985            if (app.isolated) {
5986                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5987            }
5988            boolean willRestart = false;
5989            if (app.persistent && !app.isolated) {
5990                if (!callerWillRestart) {
5991                    willRestart = true;
5992                } else {
5993                    needRestart = true;
5994                }
5995            }
5996            app.kill(reason, true);
5997            handleAppDiedLocked(app, willRestart, allowRestart);
5998            if (willRestart) {
5999                removeLruProcessLocked(app);
6000                addAppLocked(app.info, false, null /* ABI override */);
6001            }
6002        } else {
6003            mRemovedProcesses.add(app);
6004        }
6005
6006        return needRestart;
6007    }
6008
6009    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6010        cleanupAppInLaunchingProvidersLocked(app, true);
6011        removeProcessLocked(app, false, true, "timeout publishing content providers");
6012    }
6013
6014    private final void processStartTimedOutLocked(ProcessRecord app) {
6015        final int pid = app.pid;
6016        boolean gone = false;
6017        synchronized (mPidsSelfLocked) {
6018            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6019            if (knownApp != null && knownApp.thread == null) {
6020                mPidsSelfLocked.remove(pid);
6021                gone = true;
6022            }
6023        }
6024
6025        if (gone) {
6026            Slog.w(TAG, "Process " + app + " failed to attach");
6027            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6028                    pid, app.uid, app.processName);
6029            removeProcessNameLocked(app.processName, app.uid);
6030            if (mHeavyWeightProcess == app) {
6031                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6032                        mHeavyWeightProcess.userId, 0));
6033                mHeavyWeightProcess = null;
6034            }
6035            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6036            if (app.isolated) {
6037                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6038            }
6039            // Take care of any launching providers waiting for this process.
6040            cleanupAppInLaunchingProvidersLocked(app, true);
6041            // Take care of any services that are waiting for the process.
6042            mServices.processStartTimedOutLocked(app);
6043            app.kill("start timeout", true);
6044            removeLruProcessLocked(app);
6045            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6046                Slog.w(TAG, "Unattached app died before backup, skipping");
6047                try {
6048                    IBackupManager bm = IBackupManager.Stub.asInterface(
6049                            ServiceManager.getService(Context.BACKUP_SERVICE));
6050                    bm.agentDisconnected(app.info.packageName);
6051                } catch (RemoteException e) {
6052                    // Can't happen; the backup manager is local
6053                }
6054            }
6055            if (isPendingBroadcastProcessLocked(pid)) {
6056                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6057                skipPendingBroadcastLocked(pid);
6058            }
6059        } else {
6060            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6061        }
6062    }
6063
6064    private final boolean attachApplicationLocked(IApplicationThread thread,
6065            int pid) {
6066
6067        // Find the application record that is being attached...  either via
6068        // the pid if we are running in multiple processes, or just pull the
6069        // next app record if we are emulating process with anonymous threads.
6070        ProcessRecord app;
6071        if (pid != MY_PID && pid >= 0) {
6072            synchronized (mPidsSelfLocked) {
6073                app = mPidsSelfLocked.get(pid);
6074            }
6075        } else {
6076            app = null;
6077        }
6078
6079        if (app == null) {
6080            Slog.w(TAG, "No pending application record for pid " + pid
6081                    + " (IApplicationThread " + thread + "); dropping process");
6082            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6083            if (pid > 0 && pid != MY_PID) {
6084                Process.killProcessQuiet(pid);
6085                //TODO: killProcessGroup(app.info.uid, pid);
6086            } else {
6087                try {
6088                    thread.scheduleExit();
6089                } catch (Exception e) {
6090                    // Ignore exceptions.
6091                }
6092            }
6093            return false;
6094        }
6095
6096        // If this application record is still attached to a previous
6097        // process, clean it up now.
6098        if (app.thread != null) {
6099            handleAppDiedLocked(app, true, true);
6100        }
6101
6102        // Tell the process all about itself.
6103
6104        if (DEBUG_ALL) Slog.v(
6105                TAG, "Binding process pid " + pid + " to record " + app);
6106
6107        final String processName = app.processName;
6108        try {
6109            AppDeathRecipient adr = new AppDeathRecipient(
6110                    app, pid, thread);
6111            thread.asBinder().linkToDeath(adr, 0);
6112            app.deathRecipient = adr;
6113        } catch (RemoteException e) {
6114            app.resetPackageList(mProcessStats);
6115            startProcessLocked(app, "link fail", processName);
6116            return false;
6117        }
6118
6119        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6120
6121        app.makeActive(thread, mProcessStats);
6122        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6123        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6124        app.forcingToForeground = null;
6125        updateProcessForegroundLocked(app, false, false);
6126        app.hasShownUi = false;
6127        app.debugging = false;
6128        app.cached = false;
6129        app.killedByAm = false;
6130
6131        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6132
6133        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6134        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6135
6136        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6137            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6138            msg.obj = app;
6139            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6140        }
6141
6142        if (!normalMode) {
6143            Slog.i(TAG, "Launching preboot mode app: " + app);
6144        }
6145
6146        if (DEBUG_ALL) Slog.v(
6147            TAG, "New app record " + app
6148            + " thread=" + thread.asBinder() + " pid=" + pid);
6149        try {
6150            int testMode = IApplicationThread.DEBUG_OFF;
6151            if (mDebugApp != null && mDebugApp.equals(processName)) {
6152                testMode = mWaitForDebugger
6153                    ? IApplicationThread.DEBUG_WAIT
6154                    : IApplicationThread.DEBUG_ON;
6155                app.debugging = true;
6156                if (mDebugTransient) {
6157                    mDebugApp = mOrigDebugApp;
6158                    mWaitForDebugger = mOrigWaitForDebugger;
6159                }
6160            }
6161            String profileFile = app.instrumentationProfileFile;
6162            ParcelFileDescriptor profileFd = null;
6163            int samplingInterval = 0;
6164            boolean profileAutoStop = false;
6165            if (mProfileApp != null && mProfileApp.equals(processName)) {
6166                mProfileProc = app;
6167                profileFile = mProfileFile;
6168                profileFd = mProfileFd;
6169                samplingInterval = mSamplingInterval;
6170                profileAutoStop = mAutoStopProfiler;
6171            }
6172            boolean enableTrackAllocation = false;
6173            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6174                enableTrackAllocation = true;
6175                mTrackAllocationApp = null;
6176            }
6177
6178            // If the app is being launched for restore or full backup, set it up specially
6179            boolean isRestrictedBackupMode = false;
6180            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6181                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6182                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6183                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6184            }
6185
6186            notifyPackageUse(app.instrumentationInfo != null
6187                    ? app.instrumentationInfo.packageName
6188                    : app.info.packageName);
6189            if (app.instrumentationClass != null) {
6190                notifyPackageUse(app.instrumentationClass.getPackageName());
6191            }
6192            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6193                    + processName + " with config " + mConfiguration);
6194            ApplicationInfo appInfo = app.instrumentationInfo != null
6195                    ? app.instrumentationInfo : app.info;
6196            app.compat = compatibilityInfoForPackageLocked(appInfo);
6197            if (profileFd != null) {
6198                profileFd = profileFd.dup();
6199            }
6200            ProfilerInfo profilerInfo = profileFile == null ? null
6201                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6202            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6203                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6204                    app.instrumentationUiAutomationConnection, testMode,
6205                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6206                    isRestrictedBackupMode || !normalMode, app.persistent,
6207                    new Configuration(mConfiguration), app.compat,
6208                    getCommonServicesLocked(app.isolated),
6209                    mCoreSettingsObserver.getCoreSettingsLocked());
6210            updateLruProcessLocked(app, false, null);
6211            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6212        } catch (Exception e) {
6213            // todo: Yikes!  What should we do?  For now we will try to
6214            // start another process, but that could easily get us in
6215            // an infinite loop of restarting processes...
6216            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6217
6218            app.resetPackageList(mProcessStats);
6219            app.unlinkDeathRecipient();
6220            startProcessLocked(app, "bind fail", processName);
6221            return false;
6222        }
6223
6224        // Remove this record from the list of starting applications.
6225        mPersistentStartingProcesses.remove(app);
6226        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6227                "Attach application locked removing on hold: " + app);
6228        mProcessesOnHold.remove(app);
6229
6230        boolean badApp = false;
6231        boolean didSomething = false;
6232
6233        // See if the top visible activity is waiting to run in this process...
6234        if (normalMode) {
6235            try {
6236                if (mStackSupervisor.attachApplicationLocked(app)) {
6237                    didSomething = true;
6238                }
6239            } catch (Exception e) {
6240                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6241                badApp = true;
6242            }
6243        }
6244
6245        // Find any services that should be running in this process...
6246        if (!badApp) {
6247            try {
6248                didSomething |= mServices.attachApplicationLocked(app, processName);
6249            } catch (Exception e) {
6250                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6251                badApp = true;
6252            }
6253        }
6254
6255        // Check if a next-broadcast receiver is in this process...
6256        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6257            try {
6258                didSomething |= sendPendingBroadcastsLocked(app);
6259            } catch (Exception e) {
6260                // If the app died trying to launch the receiver we declare it 'bad'
6261                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6262                badApp = true;
6263            }
6264        }
6265
6266        // Check whether the next backup agent is in this process...
6267        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6268            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6269                    "New app is backup target, launching agent for " + app);
6270            notifyPackageUse(mBackupTarget.appInfo.packageName);
6271            try {
6272                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6273                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6274                        mBackupTarget.backupMode);
6275            } catch (Exception e) {
6276                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6277                badApp = true;
6278            }
6279        }
6280
6281        if (badApp) {
6282            app.kill("error during init", true);
6283            handleAppDiedLocked(app, false, true);
6284            return false;
6285        }
6286
6287        if (!didSomething) {
6288            updateOomAdjLocked();
6289        }
6290
6291        return true;
6292    }
6293
6294    @Override
6295    public final void attachApplication(IApplicationThread thread) {
6296        synchronized (this) {
6297            int callingPid = Binder.getCallingPid();
6298            final long origId = Binder.clearCallingIdentity();
6299            attachApplicationLocked(thread, callingPid);
6300            Binder.restoreCallingIdentity(origId);
6301        }
6302    }
6303
6304    @Override
6305    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6306        final long origId = Binder.clearCallingIdentity();
6307        synchronized (this) {
6308            ActivityStack stack = ActivityRecord.getStackLocked(token);
6309            if (stack != null) {
6310                ActivityRecord r =
6311                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6312                if (stopProfiling) {
6313                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6314                        try {
6315                            mProfileFd.close();
6316                        } catch (IOException e) {
6317                        }
6318                        clearProfilerLocked();
6319                    }
6320                }
6321            }
6322        }
6323        Binder.restoreCallingIdentity(origId);
6324    }
6325
6326    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6327        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6328                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6329    }
6330
6331    void enableScreenAfterBoot() {
6332        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6333                SystemClock.uptimeMillis());
6334        mWindowManager.enableScreenAfterBoot();
6335
6336        synchronized (this) {
6337            updateEventDispatchingLocked();
6338        }
6339    }
6340
6341    @Override
6342    public void showBootMessage(final CharSequence msg, final boolean always) {
6343        if (Binder.getCallingUid() != Process.myUid()) {
6344            // These days only the core system can call this, so apps can't get in
6345            // the way of what we show about running them.
6346        }
6347        mWindowManager.showBootMessage(msg, always);
6348    }
6349
6350    @Override
6351    public void keyguardWaitingForActivityDrawn() {
6352        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6353        final long token = Binder.clearCallingIdentity();
6354        try {
6355            synchronized (this) {
6356                if (DEBUG_LOCKSCREEN) logLockScreen("");
6357                mWindowManager.keyguardWaitingForActivityDrawn();
6358                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6359                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6360                    updateSleepIfNeededLocked();
6361                }
6362            }
6363        } finally {
6364            Binder.restoreCallingIdentity(token);
6365        }
6366    }
6367
6368    @Override
6369    public void keyguardGoingAway(boolean disableWindowAnimations,
6370            boolean keyguardGoingToNotificationShade) {
6371        enforceNotIsolatedCaller("keyguardGoingAway");
6372        final long token = Binder.clearCallingIdentity();
6373        try {
6374            synchronized (this) {
6375                if (DEBUG_LOCKSCREEN) logLockScreen("");
6376                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6377                        keyguardGoingToNotificationShade);
6378                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6379                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6380                    updateSleepIfNeededLocked();
6381                }
6382            }
6383        } finally {
6384            Binder.restoreCallingIdentity(token);
6385        }
6386    }
6387
6388    final void finishBooting() {
6389        synchronized (this) {
6390            if (!mBootAnimationComplete) {
6391                mCallFinishBooting = true;
6392                return;
6393            }
6394            mCallFinishBooting = false;
6395        }
6396
6397        ArraySet<String> completedIsas = new ArraySet<String>();
6398        for (String abi : Build.SUPPORTED_ABIS) {
6399            Process.establishZygoteConnectionForAbi(abi);
6400            final String instructionSet = VMRuntime.getInstructionSet(abi);
6401            if (!completedIsas.contains(instructionSet)) {
6402                try {
6403                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6404                } catch (InstallerException e) {
6405                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6406                }
6407                completedIsas.add(instructionSet);
6408            }
6409        }
6410
6411        IntentFilter pkgFilter = new IntentFilter();
6412        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6413        pkgFilter.addDataScheme("package");
6414        mContext.registerReceiver(new BroadcastReceiver() {
6415            @Override
6416            public void onReceive(Context context, Intent intent) {
6417                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6418                if (pkgs != null) {
6419                    for (String pkg : pkgs) {
6420                        synchronized (ActivityManagerService.this) {
6421                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6422                                    0, "query restart")) {
6423                                setResultCode(Activity.RESULT_OK);
6424                                return;
6425                            }
6426                        }
6427                    }
6428                }
6429            }
6430        }, pkgFilter);
6431
6432        IntentFilter dumpheapFilter = new IntentFilter();
6433        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6434        mContext.registerReceiver(new BroadcastReceiver() {
6435            @Override
6436            public void onReceive(Context context, Intent intent) {
6437                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6438                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6439                } else {
6440                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6441                }
6442            }
6443        }, dumpheapFilter);
6444
6445        mProcessStartLogger.registerListener(mContext);
6446
6447        // Let system services know.
6448        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6449
6450        synchronized (this) {
6451            // Ensure that any processes we had put on hold are now started
6452            // up.
6453            final int NP = mProcessesOnHold.size();
6454            if (NP > 0) {
6455                ArrayList<ProcessRecord> procs =
6456                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6457                for (int ip=0; ip<NP; ip++) {
6458                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6459                            + procs.get(ip));
6460                    startProcessLocked(procs.get(ip), "on-hold", null);
6461                }
6462            }
6463
6464            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6465                // Start looking for apps that are abusing wake locks.
6466                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6467                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6468                // Tell anyone interested that we are done booting!
6469                SystemProperties.set("sys.boot_completed", "1");
6470
6471                // And trigger dev.bootcomplete if we are not showing encryption progress
6472                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6473                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6474                    SystemProperties.set("dev.bootcomplete", "1");
6475                }
6476                mUserController.sendBootCompletedLocked(
6477                        new IIntentReceiver.Stub() {
6478                            @Override
6479                            public void performReceive(Intent intent, int resultCode,
6480                                    String data, Bundle extras, boolean ordered,
6481                                    boolean sticky, int sendingUser) {
6482                                synchronized (ActivityManagerService.this) {
6483                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6484                                            true, false);
6485                                }
6486                            }
6487                        });
6488                scheduleStartProfilesLocked();
6489            }
6490        }
6491    }
6492
6493    @Override
6494    public void bootAnimationComplete() {
6495        final boolean callFinishBooting;
6496        synchronized (this) {
6497            callFinishBooting = mCallFinishBooting;
6498            mBootAnimationComplete = true;
6499        }
6500        if (callFinishBooting) {
6501            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6502            finishBooting();
6503            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6504        }
6505    }
6506
6507    final void ensureBootCompleted() {
6508        boolean booting;
6509        boolean enableScreen;
6510        synchronized (this) {
6511            booting = mBooting;
6512            mBooting = false;
6513            enableScreen = !mBooted;
6514            mBooted = true;
6515        }
6516
6517        if (booting) {
6518            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6519            finishBooting();
6520            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6521        }
6522
6523        if (enableScreen) {
6524            enableScreenAfterBoot();
6525        }
6526    }
6527
6528    @Override
6529    public final void activityResumed(IBinder token) {
6530        final long origId = Binder.clearCallingIdentity();
6531        synchronized(this) {
6532            ActivityStack stack = ActivityRecord.getStackLocked(token);
6533            if (stack != null) {
6534                ActivityRecord.activityResumedLocked(token);
6535            }
6536        }
6537        Binder.restoreCallingIdentity(origId);
6538    }
6539
6540    @Override
6541    public final void activityPaused(IBinder token) {
6542        final long origId = Binder.clearCallingIdentity();
6543        synchronized(this) {
6544            ActivityStack stack = ActivityRecord.getStackLocked(token);
6545            if (stack != null) {
6546                stack.activityPausedLocked(token, false);
6547            }
6548        }
6549        Binder.restoreCallingIdentity(origId);
6550    }
6551
6552    @Override
6553    public final void activityStopped(IBinder token, Bundle icicle,
6554            PersistableBundle persistentState, CharSequence description) {
6555        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6556
6557        // Refuse possible leaked file descriptors
6558        if (icicle != null && icicle.hasFileDescriptors()) {
6559            throw new IllegalArgumentException("File descriptors passed in Bundle");
6560        }
6561
6562        final long origId = Binder.clearCallingIdentity();
6563
6564        synchronized (this) {
6565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6566            if (r != null) {
6567                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6568            }
6569        }
6570
6571        trimApplications();
6572
6573        Binder.restoreCallingIdentity(origId);
6574    }
6575
6576    @Override
6577    public final void activityDestroyed(IBinder token) {
6578        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6579        synchronized (this) {
6580            ActivityStack stack = ActivityRecord.getStackLocked(token);
6581            if (stack != null) {
6582                stack.activityDestroyedLocked(token, "activityDestroyed");
6583            }
6584        }
6585    }
6586
6587    @Override
6588    public final void activityRelaunched(IBinder token) {
6589        final long origId = Binder.clearCallingIdentity();
6590        synchronized (this) {
6591            mStackSupervisor.activityRelaunchedLocked(token);
6592        }
6593        Binder.restoreCallingIdentity(origId);
6594    }
6595
6596    @Override
6597    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6598            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6599        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6600                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6601        synchronized (this) {
6602            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6603            if (record == null) {
6604                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6605                        + "found for: " + token);
6606            }
6607            record.setSizeConfigurations(horizontalSizeConfiguration,
6608                    verticalSizeConfigurations, smallestSizeConfigurations);
6609        }
6610    }
6611
6612    @Override
6613    public final void backgroundResourcesReleased(IBinder token) {
6614        final long origId = Binder.clearCallingIdentity();
6615        try {
6616            synchronized (this) {
6617                ActivityStack stack = ActivityRecord.getStackLocked(token);
6618                if (stack != null) {
6619                    stack.backgroundResourcesReleased();
6620                }
6621            }
6622        } finally {
6623            Binder.restoreCallingIdentity(origId);
6624        }
6625    }
6626
6627    @Override
6628    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6629        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6630    }
6631
6632    @Override
6633    public final void notifyEnterAnimationComplete(IBinder token) {
6634        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6635    }
6636
6637    @Override
6638    public String getCallingPackage(IBinder token) {
6639        synchronized (this) {
6640            ActivityRecord r = getCallingRecordLocked(token);
6641            return r != null ? r.info.packageName : null;
6642        }
6643    }
6644
6645    @Override
6646    public ComponentName getCallingActivity(IBinder token) {
6647        synchronized (this) {
6648            ActivityRecord r = getCallingRecordLocked(token);
6649            return r != null ? r.intent.getComponent() : null;
6650        }
6651    }
6652
6653    private ActivityRecord getCallingRecordLocked(IBinder token) {
6654        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6655        if (r == null) {
6656            return null;
6657        }
6658        return r.resultTo;
6659    }
6660
6661    @Override
6662    public ComponentName getActivityClassForToken(IBinder token) {
6663        synchronized(this) {
6664            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6665            if (r == null) {
6666                return null;
6667            }
6668            return r.intent.getComponent();
6669        }
6670    }
6671
6672    @Override
6673    public String getPackageForToken(IBinder token) {
6674        synchronized(this) {
6675            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6676            if (r == null) {
6677                return null;
6678            }
6679            return r.packageName;
6680        }
6681    }
6682
6683    @Override
6684    public boolean isRootVoiceInteraction(IBinder token) {
6685        synchronized(this) {
6686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6687            if (r == null) {
6688                return false;
6689            }
6690            return r.rootVoiceInteraction;
6691        }
6692    }
6693
6694    @Override
6695    public IIntentSender getIntentSender(int type,
6696            String packageName, IBinder token, String resultWho,
6697            int requestCode, Intent[] intents, String[] resolvedTypes,
6698            int flags, Bundle bOptions, int userId) {
6699        enforceNotIsolatedCaller("getIntentSender");
6700        // Refuse possible leaked file descriptors
6701        if (intents != null) {
6702            if (intents.length < 1) {
6703                throw new IllegalArgumentException("Intents array length must be >= 1");
6704            }
6705            for (int i=0; i<intents.length; i++) {
6706                Intent intent = intents[i];
6707                if (intent != null) {
6708                    if (intent.hasFileDescriptors()) {
6709                        throw new IllegalArgumentException("File descriptors passed in Intent");
6710                    }
6711                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6712                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6713                        throw new IllegalArgumentException(
6714                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6715                    }
6716                    intents[i] = new Intent(intent);
6717                }
6718            }
6719            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6720                throw new IllegalArgumentException(
6721                        "Intent array length does not match resolvedTypes length");
6722            }
6723        }
6724        if (bOptions != null) {
6725            if (bOptions.hasFileDescriptors()) {
6726                throw new IllegalArgumentException("File descriptors passed in options");
6727            }
6728        }
6729
6730        synchronized(this) {
6731            int callingUid = Binder.getCallingUid();
6732            int origUserId = userId;
6733            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6734                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6735                    ALLOW_NON_FULL, "getIntentSender", null);
6736            if (origUserId == UserHandle.USER_CURRENT) {
6737                // We don't want to evaluate this until the pending intent is
6738                // actually executed.  However, we do want to always do the
6739                // security checking for it above.
6740                userId = UserHandle.USER_CURRENT;
6741            }
6742            try {
6743                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6744                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6745                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6746                    if (!UserHandle.isSameApp(callingUid, uid)) {
6747                        String msg = "Permission Denial: getIntentSender() from pid="
6748                            + Binder.getCallingPid()
6749                            + ", uid=" + Binder.getCallingUid()
6750                            + ", (need uid=" + uid + ")"
6751                            + " is not allowed to send as package " + packageName;
6752                        Slog.w(TAG, msg);
6753                        throw new SecurityException(msg);
6754                    }
6755                }
6756
6757                return getIntentSenderLocked(type, packageName, callingUid, userId,
6758                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6759
6760            } catch (RemoteException e) {
6761                throw new SecurityException(e);
6762            }
6763        }
6764    }
6765
6766    IIntentSender getIntentSenderLocked(int type, String packageName,
6767            int callingUid, int userId, IBinder token, String resultWho,
6768            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6769            Bundle bOptions) {
6770        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6771        ActivityRecord activity = null;
6772        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6773            activity = ActivityRecord.isInStackLocked(token);
6774            if (activity == null) {
6775                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6776                return null;
6777            }
6778            if (activity.finishing) {
6779                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6780                return null;
6781            }
6782        }
6783
6784        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6785        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6786        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6787        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6788                |PendingIntent.FLAG_UPDATE_CURRENT);
6789
6790        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6791                type, packageName, activity, resultWho,
6792                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6793        WeakReference<PendingIntentRecord> ref;
6794        ref = mIntentSenderRecords.get(key);
6795        PendingIntentRecord rec = ref != null ? ref.get() : null;
6796        if (rec != null) {
6797            if (!cancelCurrent) {
6798                if (updateCurrent) {
6799                    if (rec.key.requestIntent != null) {
6800                        rec.key.requestIntent.replaceExtras(intents != null ?
6801                                intents[intents.length - 1] : null);
6802                    }
6803                    if (intents != null) {
6804                        intents[intents.length-1] = rec.key.requestIntent;
6805                        rec.key.allIntents = intents;
6806                        rec.key.allResolvedTypes = resolvedTypes;
6807                    } else {
6808                        rec.key.allIntents = null;
6809                        rec.key.allResolvedTypes = null;
6810                    }
6811                }
6812                return rec;
6813            }
6814            rec.canceled = true;
6815            mIntentSenderRecords.remove(key);
6816        }
6817        if (noCreate) {
6818            return rec;
6819        }
6820        rec = new PendingIntentRecord(this, key, callingUid);
6821        mIntentSenderRecords.put(key, rec.ref);
6822        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6823            if (activity.pendingResults == null) {
6824                activity.pendingResults
6825                        = new HashSet<WeakReference<PendingIntentRecord>>();
6826            }
6827            activity.pendingResults.add(rec.ref);
6828        }
6829        return rec;
6830    }
6831
6832    @Override
6833    public void cancelIntentSender(IIntentSender sender) {
6834        if (!(sender instanceof PendingIntentRecord)) {
6835            return;
6836        }
6837        synchronized(this) {
6838            PendingIntentRecord rec = (PendingIntentRecord)sender;
6839            try {
6840                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
6841                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
6842                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6843                    String msg = "Permission Denial: cancelIntentSender() from pid="
6844                        + Binder.getCallingPid()
6845                        + ", uid=" + Binder.getCallingUid()
6846                        + " is not allowed to cancel packges "
6847                        + rec.key.packageName;
6848                    Slog.w(TAG, msg);
6849                    throw new SecurityException(msg);
6850                }
6851            } catch (RemoteException e) {
6852                throw new SecurityException(e);
6853            }
6854            cancelIntentSenderLocked(rec, true);
6855        }
6856    }
6857
6858    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6859        rec.canceled = true;
6860        mIntentSenderRecords.remove(rec.key);
6861        if (cleanActivity && rec.key.activity != null) {
6862            rec.key.activity.pendingResults.remove(rec.ref);
6863        }
6864    }
6865
6866    @Override
6867    public String getPackageForIntentSender(IIntentSender pendingResult) {
6868        if (!(pendingResult instanceof PendingIntentRecord)) {
6869            return null;
6870        }
6871        try {
6872            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6873            return res.key.packageName;
6874        } catch (ClassCastException e) {
6875        }
6876        return null;
6877    }
6878
6879    @Override
6880    public int getUidForIntentSender(IIntentSender sender) {
6881        if (sender instanceof PendingIntentRecord) {
6882            try {
6883                PendingIntentRecord res = (PendingIntentRecord)sender;
6884                return res.uid;
6885            } catch (ClassCastException e) {
6886            }
6887        }
6888        return -1;
6889    }
6890
6891    @Override
6892    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6893        if (!(pendingResult instanceof PendingIntentRecord)) {
6894            return false;
6895        }
6896        try {
6897            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6898            if (res.key.allIntents == null) {
6899                return false;
6900            }
6901            for (int i=0; i<res.key.allIntents.length; i++) {
6902                Intent intent = res.key.allIntents[i];
6903                if (intent.getPackage() != null && intent.getComponent() != null) {
6904                    return false;
6905                }
6906            }
6907            return true;
6908        } catch (ClassCastException e) {
6909        }
6910        return false;
6911    }
6912
6913    @Override
6914    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6915        if (!(pendingResult instanceof PendingIntentRecord)) {
6916            return false;
6917        }
6918        try {
6919            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6920            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6921                return true;
6922            }
6923            return false;
6924        } catch (ClassCastException e) {
6925        }
6926        return false;
6927    }
6928
6929    @Override
6930    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6931        if (!(pendingResult instanceof PendingIntentRecord)) {
6932            return null;
6933        }
6934        try {
6935            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6936            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6937        } catch (ClassCastException e) {
6938        }
6939        return null;
6940    }
6941
6942    @Override
6943    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6944        if (!(pendingResult instanceof PendingIntentRecord)) {
6945            return null;
6946        }
6947        try {
6948            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6949            synchronized (this) {
6950                return getTagForIntentSenderLocked(res, prefix);
6951            }
6952        } catch (ClassCastException e) {
6953        }
6954        return null;
6955    }
6956
6957    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6958        final Intent intent = res.key.requestIntent;
6959        if (intent != null) {
6960            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6961                    || res.lastTagPrefix.equals(prefix))) {
6962                return res.lastTag;
6963            }
6964            res.lastTagPrefix = prefix;
6965            final StringBuilder sb = new StringBuilder(128);
6966            if (prefix != null) {
6967                sb.append(prefix);
6968            }
6969            if (intent.getAction() != null) {
6970                sb.append(intent.getAction());
6971            } else if (intent.getComponent() != null) {
6972                intent.getComponent().appendShortString(sb);
6973            } else {
6974                sb.append("?");
6975            }
6976            return res.lastTag = sb.toString();
6977        }
6978        return null;
6979    }
6980
6981    @Override
6982    public void setProcessLimit(int max) {
6983        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6984                "setProcessLimit()");
6985        synchronized (this) {
6986            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6987            mProcessLimitOverride = max;
6988        }
6989        trimApplications();
6990    }
6991
6992    @Override
6993    public int getProcessLimit() {
6994        synchronized (this) {
6995            return mProcessLimitOverride;
6996        }
6997    }
6998
6999    void foregroundTokenDied(ForegroundToken token) {
7000        synchronized (ActivityManagerService.this) {
7001            synchronized (mPidsSelfLocked) {
7002                ForegroundToken cur
7003                    = mForegroundProcesses.get(token.pid);
7004                if (cur != token) {
7005                    return;
7006                }
7007                mForegroundProcesses.remove(token.pid);
7008                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7009                if (pr == null) {
7010                    return;
7011                }
7012                pr.forcingToForeground = null;
7013                updateProcessForegroundLocked(pr, false, false);
7014            }
7015            updateOomAdjLocked();
7016        }
7017    }
7018
7019    @Override
7020    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7021        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7022                "setProcessForeground()");
7023        synchronized(this) {
7024            boolean changed = false;
7025
7026            synchronized (mPidsSelfLocked) {
7027                ProcessRecord pr = mPidsSelfLocked.get(pid);
7028                if (pr == null && isForeground) {
7029                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7030                    return;
7031                }
7032                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7033                if (oldToken != null) {
7034                    oldToken.token.unlinkToDeath(oldToken, 0);
7035                    mForegroundProcesses.remove(pid);
7036                    if (pr != null) {
7037                        pr.forcingToForeground = null;
7038                    }
7039                    changed = true;
7040                }
7041                if (isForeground && token != null) {
7042                    ForegroundToken newToken = new ForegroundToken() {
7043                        @Override
7044                        public void binderDied() {
7045                            foregroundTokenDied(this);
7046                        }
7047                    };
7048                    newToken.pid = pid;
7049                    newToken.token = token;
7050                    try {
7051                        token.linkToDeath(newToken, 0);
7052                        mForegroundProcesses.put(pid, newToken);
7053                        pr.forcingToForeground = token;
7054                        changed = true;
7055                    } catch (RemoteException e) {
7056                        // If the process died while doing this, we will later
7057                        // do the cleanup with the process death link.
7058                    }
7059                }
7060            }
7061
7062            if (changed) {
7063                updateOomAdjLocked();
7064            }
7065        }
7066    }
7067
7068    @Override
7069    public boolean isAppForeground(int uid) throws RemoteException {
7070        synchronized (this) {
7071            UidRecord uidRec = mActiveUids.get(uid);
7072            if (uidRec == null || uidRec.idle) {
7073                return false;
7074            }
7075            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7076        }
7077    }
7078
7079    @Override
7080    public boolean inMultiWindow(IBinder token) {
7081        final long origId = Binder.clearCallingIdentity();
7082        try {
7083            synchronized(this) {
7084                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7085                if (r == null) {
7086                    return false;
7087                }
7088                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7089                return !r.task.mFullscreen;
7090            }
7091        } finally {
7092            Binder.restoreCallingIdentity(origId);
7093        }
7094    }
7095
7096    @Override
7097    public boolean inPictureInPicture(IBinder token) {
7098        final long origId = Binder.clearCallingIdentity();
7099        try {
7100            synchronized(this) {
7101                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7102                if (stack == null) {
7103                    return false;
7104                }
7105                return stack.mStackId == PINNED_STACK_ID;
7106            }
7107        } finally {
7108            Binder.restoreCallingIdentity(origId);
7109        }
7110    }
7111
7112    @Override
7113    public void enterPictureInPicture(IBinder token) {
7114        final long origId = Binder.clearCallingIdentity();
7115        try {
7116            synchronized(this) {
7117                if (!mSupportsPictureInPicture) {
7118                    throw new IllegalStateException("enterPictureInPicture: "
7119                            + "Device doesn't support picture-in-picture mode.");
7120                }
7121
7122                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7123
7124                if (r == null) {
7125                    throw new IllegalStateException("enterPictureInPicture: "
7126                            + "Can't find activity for token=" + token);
7127                }
7128
7129                if (!r.supportsPictureInPicture()) {
7130                    throw new IllegalArgumentException("enterPictureInPicture: "
7131                            + "Picture-In-Picture not supported for r=" + r);
7132                }
7133
7134                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7135                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7136                        ? mDefaultPinnedStackBounds : null;
7137
7138                mStackSupervisor.moveActivityToStackLocked(
7139                        r, PINNED_STACK_ID, "enterPictureInPicture", bounds);
7140            }
7141        } finally {
7142            Binder.restoreCallingIdentity(origId);
7143        }
7144    }
7145
7146    // =========================================================
7147    // PROCESS INFO
7148    // =========================================================
7149
7150    static class ProcessInfoService extends IProcessInfoService.Stub {
7151        final ActivityManagerService mActivityManagerService;
7152        ProcessInfoService(ActivityManagerService activityManagerService) {
7153            mActivityManagerService = activityManagerService;
7154        }
7155
7156        @Override
7157        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7158            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7159                    /*in*/ pids, /*out*/ states, null);
7160        }
7161
7162        @Override
7163        public void getProcessStatesAndOomScoresFromPids(
7164                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7165            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7166                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7167        }
7168    }
7169
7170    /**
7171     * For each PID in the given input array, write the current process state
7172     * for that process into the states array, or -1 to indicate that no
7173     * process with the given PID exists. If scores array is provided, write
7174     * the oom score for the process into the scores array, with INVALID_ADJ
7175     * indicating the PID doesn't exist.
7176     */
7177    public void getProcessStatesAndOomScoresForPIDs(
7178            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7179        if (scores != null) {
7180            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7181                    "getProcessStatesAndOomScoresForPIDs()");
7182        }
7183
7184        if (pids == null) {
7185            throw new NullPointerException("pids");
7186        } else if (states == null) {
7187            throw new NullPointerException("states");
7188        } else if (pids.length != states.length) {
7189            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7190        } else if (scores != null && pids.length != scores.length) {
7191            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7192        }
7193
7194        synchronized (mPidsSelfLocked) {
7195            for (int i = 0; i < pids.length; i++) {
7196                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7197                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7198                        pr.curProcState;
7199                if (scores != null) {
7200                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7201                }
7202            }
7203        }
7204    }
7205
7206    // =========================================================
7207    // PERMISSIONS
7208    // =========================================================
7209
7210    static class PermissionController extends IPermissionController.Stub {
7211        ActivityManagerService mActivityManagerService;
7212        PermissionController(ActivityManagerService activityManagerService) {
7213            mActivityManagerService = activityManagerService;
7214        }
7215
7216        @Override
7217        public boolean checkPermission(String permission, int pid, int uid) {
7218            return mActivityManagerService.checkPermission(permission, pid,
7219                    uid) == PackageManager.PERMISSION_GRANTED;
7220        }
7221
7222        @Override
7223        public String[] getPackagesForUid(int uid) {
7224            return mActivityManagerService.mContext.getPackageManager()
7225                    .getPackagesForUid(uid);
7226        }
7227
7228        @Override
7229        public boolean isRuntimePermission(String permission) {
7230            try {
7231                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7232                        .getPermissionInfo(permission, 0);
7233                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7234            } catch (NameNotFoundException nnfe) {
7235                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7236            }
7237            return false;
7238        }
7239    }
7240
7241    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7242        @Override
7243        public int checkComponentPermission(String permission, int pid, int uid,
7244                int owningUid, boolean exported) {
7245            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7246                    owningUid, exported);
7247        }
7248
7249        @Override
7250        public Object getAMSLock() {
7251            return ActivityManagerService.this;
7252        }
7253    }
7254
7255    /**
7256     * This can be called with or without the global lock held.
7257     */
7258    int checkComponentPermission(String permission, int pid, int uid,
7259            int owningUid, boolean exported) {
7260        if (pid == MY_PID) {
7261            return PackageManager.PERMISSION_GRANTED;
7262        }
7263        return ActivityManager.checkComponentPermission(permission, uid,
7264                owningUid, exported);
7265    }
7266
7267    /**
7268     * As the only public entry point for permissions checking, this method
7269     * can enforce the semantic that requesting a check on a null global
7270     * permission is automatically denied.  (Internally a null permission
7271     * string is used when calling {@link #checkComponentPermission} in cases
7272     * when only uid-based security is needed.)
7273     *
7274     * This can be called with or without the global lock held.
7275     */
7276    @Override
7277    public int checkPermission(String permission, int pid, int uid) {
7278        if (permission == null) {
7279            return PackageManager.PERMISSION_DENIED;
7280        }
7281        return checkComponentPermission(permission, pid, uid, -1, true);
7282    }
7283
7284    @Override
7285    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7286        if (permission == null) {
7287            return PackageManager.PERMISSION_DENIED;
7288        }
7289
7290        // We might be performing an operation on behalf of an indirect binder
7291        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7292        // client identity accordingly before proceeding.
7293        Identity tlsIdentity = sCallerIdentity.get();
7294        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7295            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7296                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7297            uid = tlsIdentity.uid;
7298            pid = tlsIdentity.pid;
7299        }
7300
7301        return checkComponentPermission(permission, pid, uid, -1, true);
7302    }
7303
7304    /**
7305     * Binder IPC calls go through the public entry point.
7306     * This can be called with or without the global lock held.
7307     */
7308    int checkCallingPermission(String permission) {
7309        return checkPermission(permission,
7310                Binder.getCallingPid(),
7311                UserHandle.getAppId(Binder.getCallingUid()));
7312    }
7313
7314    /**
7315     * This can be called with or without the global lock held.
7316     */
7317    void enforceCallingPermission(String permission, String func) {
7318        if (checkCallingPermission(permission)
7319                == PackageManager.PERMISSION_GRANTED) {
7320            return;
7321        }
7322
7323        String msg = "Permission Denial: " + func + " from pid="
7324                + Binder.getCallingPid()
7325                + ", uid=" + Binder.getCallingUid()
7326                + " requires " + permission;
7327        Slog.w(TAG, msg);
7328        throw new SecurityException(msg);
7329    }
7330
7331    /**
7332     * Determine if UID is holding permissions required to access {@link Uri} in
7333     * the given {@link ProviderInfo}. Final permission checking is always done
7334     * in {@link ContentProvider}.
7335     */
7336    private final boolean checkHoldingPermissionsLocked(
7337            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7338        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7339                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7340        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7341            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7342                    != PERMISSION_GRANTED) {
7343                return false;
7344            }
7345        }
7346        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7347    }
7348
7349    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7350            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7351        if (pi.applicationInfo.uid == uid) {
7352            return true;
7353        } else if (!pi.exported) {
7354            return false;
7355        }
7356
7357        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7358        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7359        try {
7360            // check if target holds top-level <provider> permissions
7361            if (!readMet && pi.readPermission != null && considerUidPermissions
7362                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7363                readMet = true;
7364            }
7365            if (!writeMet && pi.writePermission != null && considerUidPermissions
7366                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7367                writeMet = true;
7368            }
7369
7370            // track if unprotected read/write is allowed; any denied
7371            // <path-permission> below removes this ability
7372            boolean allowDefaultRead = pi.readPermission == null;
7373            boolean allowDefaultWrite = pi.writePermission == null;
7374
7375            // check if target holds any <path-permission> that match uri
7376            final PathPermission[] pps = pi.pathPermissions;
7377            if (pps != null) {
7378                final String path = grantUri.uri.getPath();
7379                int i = pps.length;
7380                while (i > 0 && (!readMet || !writeMet)) {
7381                    i--;
7382                    PathPermission pp = pps[i];
7383                    if (pp.match(path)) {
7384                        if (!readMet) {
7385                            final String pprperm = pp.getReadPermission();
7386                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7387                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7388                                    + ": match=" + pp.match(path)
7389                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7390                            if (pprperm != null) {
7391                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7392                                        == PERMISSION_GRANTED) {
7393                                    readMet = true;
7394                                } else {
7395                                    allowDefaultRead = false;
7396                                }
7397                            }
7398                        }
7399                        if (!writeMet) {
7400                            final String ppwperm = pp.getWritePermission();
7401                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7402                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7403                                    + ": match=" + pp.match(path)
7404                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7405                            if (ppwperm != null) {
7406                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7407                                        == PERMISSION_GRANTED) {
7408                                    writeMet = true;
7409                                } else {
7410                                    allowDefaultWrite = false;
7411                                }
7412                            }
7413                        }
7414                    }
7415                }
7416            }
7417
7418            // grant unprotected <provider> read/write, if not blocked by
7419            // <path-permission> above
7420            if (allowDefaultRead) readMet = true;
7421            if (allowDefaultWrite) writeMet = true;
7422
7423        } catch (RemoteException e) {
7424            return false;
7425        }
7426
7427        return readMet && writeMet;
7428    }
7429
7430    public int getAppStartMode(int uid, String packageName) {
7431        synchronized (this) {
7432            return checkAllowBackgroundLocked(uid, packageName, -1);
7433        }
7434    }
7435
7436    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7437        UidRecord uidRec = mActiveUids.get(uid);
7438        if (uidRec == null || uidRec.idle) {
7439            if (callingPid >= 0) {
7440                ProcessRecord proc;
7441                synchronized (mPidsSelfLocked) {
7442                    proc = mPidsSelfLocked.get(callingPid);
7443                }
7444                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7445                    // Whoever is instigating this is in the foreground, so we will allow it
7446                    // to go through.
7447                    return ActivityManager.APP_START_MODE_NORMAL;
7448                }
7449            }
7450            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7451                    != AppOpsManager.MODE_ALLOWED) {
7452                return ActivityManager.APP_START_MODE_DELAYED;
7453            }
7454        }
7455        return ActivityManager.APP_START_MODE_NORMAL;
7456    }
7457
7458    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7459        ProviderInfo pi = null;
7460        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7461        if (cpr != null) {
7462            pi = cpr.info;
7463        } else {
7464            try {
7465                pi = AppGlobals.getPackageManager().resolveContentProvider(
7466                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7467            } catch (RemoteException ex) {
7468            }
7469        }
7470        return pi;
7471    }
7472
7473    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7474        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7475        if (targetUris != null) {
7476            return targetUris.get(grantUri);
7477        }
7478        return null;
7479    }
7480
7481    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7482            String targetPkg, int targetUid, GrantUri grantUri) {
7483        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7484        if (targetUris == null) {
7485            targetUris = Maps.newArrayMap();
7486            mGrantedUriPermissions.put(targetUid, targetUris);
7487        }
7488
7489        UriPermission perm = targetUris.get(grantUri);
7490        if (perm == null) {
7491            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7492            targetUris.put(grantUri, perm);
7493        }
7494
7495        return perm;
7496    }
7497
7498    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7499            final int modeFlags) {
7500        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7501        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7502                : UriPermission.STRENGTH_OWNED;
7503
7504        // Root gets to do everything.
7505        if (uid == 0) {
7506            return true;
7507        }
7508
7509        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7510        if (perms == null) return false;
7511
7512        // First look for exact match
7513        final UriPermission exactPerm = perms.get(grantUri);
7514        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7515            return true;
7516        }
7517
7518        // No exact match, look for prefixes
7519        final int N = perms.size();
7520        for (int i = 0; i < N; i++) {
7521            final UriPermission perm = perms.valueAt(i);
7522            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7523                    && perm.getStrength(modeFlags) >= minStrength) {
7524                return true;
7525            }
7526        }
7527
7528        return false;
7529    }
7530
7531    /**
7532     * @param uri This uri must NOT contain an embedded userId.
7533     * @param userId The userId in which the uri is to be resolved.
7534     */
7535    @Override
7536    public int checkUriPermission(Uri uri, int pid, int uid,
7537            final int modeFlags, int userId, IBinder callerToken) {
7538        enforceNotIsolatedCaller("checkUriPermission");
7539
7540        // Another redirected-binder-call permissions check as in
7541        // {@link checkPermissionWithToken}.
7542        Identity tlsIdentity = sCallerIdentity.get();
7543        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7544            uid = tlsIdentity.uid;
7545            pid = tlsIdentity.pid;
7546        }
7547
7548        // Our own process gets to do everything.
7549        if (pid == MY_PID) {
7550            return PackageManager.PERMISSION_GRANTED;
7551        }
7552        synchronized (this) {
7553            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7554                    ? PackageManager.PERMISSION_GRANTED
7555                    : PackageManager.PERMISSION_DENIED;
7556        }
7557    }
7558
7559    /**
7560     * Check if the targetPkg can be granted permission to access uri by
7561     * the callingUid using the given modeFlags.  Throws a security exception
7562     * if callingUid is not allowed to do this.  Returns the uid of the target
7563     * if the URI permission grant should be performed; returns -1 if it is not
7564     * needed (for example targetPkg already has permission to access the URI).
7565     * If you already know the uid of the target, you can supply it in
7566     * lastTargetUid else set that to -1.
7567     */
7568    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7569            final int modeFlags, int lastTargetUid) {
7570        if (!Intent.isAccessUriMode(modeFlags)) {
7571            return -1;
7572        }
7573
7574        if (targetPkg != null) {
7575            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7576                    "Checking grant " + targetPkg + " permission to " + grantUri);
7577        }
7578
7579        final IPackageManager pm = AppGlobals.getPackageManager();
7580
7581        // If this is not a content: uri, we can't do anything with it.
7582        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7583            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7584                    "Can't grant URI permission for non-content URI: " + grantUri);
7585            return -1;
7586        }
7587
7588        final String authority = grantUri.uri.getAuthority();
7589        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7590        if (pi == null) {
7591            Slog.w(TAG, "No content provider found for permission check: " +
7592                    grantUri.uri.toSafeString());
7593            return -1;
7594        }
7595
7596        int targetUid = lastTargetUid;
7597        if (targetUid < 0 && targetPkg != null) {
7598            try {
7599                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7600                        UserHandle.getUserId(callingUid));
7601                if (targetUid < 0) {
7602                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7603                            "Can't grant URI permission no uid for: " + targetPkg);
7604                    return -1;
7605                }
7606            } catch (RemoteException ex) {
7607                return -1;
7608            }
7609        }
7610
7611        if (targetUid >= 0) {
7612            // First...  does the target actually need this permission?
7613            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7614                // No need to grant the target this permission.
7615                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7616                        "Target " + targetPkg + " already has full permission to " + grantUri);
7617                return -1;
7618            }
7619        } else {
7620            // First...  there is no target package, so can anyone access it?
7621            boolean allowed = pi.exported;
7622            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7623                if (pi.readPermission != null) {
7624                    allowed = false;
7625                }
7626            }
7627            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7628                if (pi.writePermission != null) {
7629                    allowed = false;
7630                }
7631            }
7632            if (allowed) {
7633                return -1;
7634            }
7635        }
7636
7637        /* There is a special cross user grant if:
7638         * - The target is on another user.
7639         * - Apps on the current user can access the uri without any uid permissions.
7640         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7641         * grant uri permissions.
7642         */
7643        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7644                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7645                modeFlags, false /*without considering the uid permissions*/);
7646
7647        // Second...  is the provider allowing granting of URI permissions?
7648        if (!specialCrossUserGrant) {
7649            if (!pi.grantUriPermissions) {
7650                throw new SecurityException("Provider " + pi.packageName
7651                        + "/" + pi.name
7652                        + " does not allow granting of Uri permissions (uri "
7653                        + grantUri + ")");
7654            }
7655            if (pi.uriPermissionPatterns != null) {
7656                final int N = pi.uriPermissionPatterns.length;
7657                boolean allowed = false;
7658                for (int i=0; i<N; i++) {
7659                    if (pi.uriPermissionPatterns[i] != null
7660                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7661                        allowed = true;
7662                        break;
7663                    }
7664                }
7665                if (!allowed) {
7666                    throw new SecurityException("Provider " + pi.packageName
7667                            + "/" + pi.name
7668                            + " does not allow granting of permission to path of Uri "
7669                            + grantUri);
7670                }
7671            }
7672        }
7673
7674        // Third...  does the caller itself have permission to access
7675        // this uri?
7676        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7677            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7678                // Require they hold a strong enough Uri permission
7679                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7680                    throw new SecurityException("Uid " + callingUid
7681                            + " does not have permission to uri " + grantUri);
7682                }
7683            }
7684        }
7685        return targetUid;
7686    }
7687
7688    /**
7689     * @param uri This uri must NOT contain an embedded userId.
7690     * @param userId The userId in which the uri is to be resolved.
7691     */
7692    @Override
7693    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7694            final int modeFlags, int userId) {
7695        enforceNotIsolatedCaller("checkGrantUriPermission");
7696        synchronized(this) {
7697            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7698                    new GrantUri(userId, uri, false), modeFlags, -1);
7699        }
7700    }
7701
7702    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7703            final int modeFlags, UriPermissionOwner owner) {
7704        if (!Intent.isAccessUriMode(modeFlags)) {
7705            return;
7706        }
7707
7708        // So here we are: the caller has the assumed permission
7709        // to the uri, and the target doesn't.  Let's now give this to
7710        // the target.
7711
7712        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7713                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7714
7715        final String authority = grantUri.uri.getAuthority();
7716        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7717        if (pi == null) {
7718            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7719            return;
7720        }
7721
7722        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7723            grantUri.prefix = true;
7724        }
7725        final UriPermission perm = findOrCreateUriPermissionLocked(
7726                pi.packageName, targetPkg, targetUid, grantUri);
7727        perm.grantModes(modeFlags, owner);
7728    }
7729
7730    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7731            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7732        if (targetPkg == null) {
7733            throw new NullPointerException("targetPkg");
7734        }
7735        int targetUid;
7736        final IPackageManager pm = AppGlobals.getPackageManager();
7737        try {
7738            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7739        } catch (RemoteException ex) {
7740            return;
7741        }
7742
7743        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7744                targetUid);
7745        if (targetUid < 0) {
7746            return;
7747        }
7748
7749        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7750                owner);
7751    }
7752
7753    static class NeededUriGrants extends ArrayList<GrantUri> {
7754        final String targetPkg;
7755        final int targetUid;
7756        final int flags;
7757
7758        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7759            this.targetPkg = targetPkg;
7760            this.targetUid = targetUid;
7761            this.flags = flags;
7762        }
7763    }
7764
7765    /**
7766     * Like checkGrantUriPermissionLocked, but takes an Intent.
7767     */
7768    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7769            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7770        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7771                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7772                + " clip=" + (intent != null ? intent.getClipData() : null)
7773                + " from " + intent + "; flags=0x"
7774                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7775
7776        if (targetPkg == null) {
7777            throw new NullPointerException("targetPkg");
7778        }
7779
7780        if (intent == null) {
7781            return null;
7782        }
7783        Uri data = intent.getData();
7784        ClipData clip = intent.getClipData();
7785        if (data == null && clip == null) {
7786            return null;
7787        }
7788        // Default userId for uris in the intent (if they don't specify it themselves)
7789        int contentUserHint = intent.getContentUserHint();
7790        if (contentUserHint == UserHandle.USER_CURRENT) {
7791            contentUserHint = UserHandle.getUserId(callingUid);
7792        }
7793        final IPackageManager pm = AppGlobals.getPackageManager();
7794        int targetUid;
7795        if (needed != null) {
7796            targetUid = needed.targetUid;
7797        } else {
7798            try {
7799                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7800                        targetUserId);
7801            } catch (RemoteException ex) {
7802                return null;
7803            }
7804            if (targetUid < 0) {
7805                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7806                        "Can't grant URI permission no uid for: " + targetPkg
7807                        + " on user " + targetUserId);
7808                return null;
7809            }
7810        }
7811        if (data != null) {
7812            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7813            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7814                    targetUid);
7815            if (targetUid > 0) {
7816                if (needed == null) {
7817                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7818                }
7819                needed.add(grantUri);
7820            }
7821        }
7822        if (clip != null) {
7823            for (int i=0; i<clip.getItemCount(); i++) {
7824                Uri uri = clip.getItemAt(i).getUri();
7825                if (uri != null) {
7826                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7827                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7828                            targetUid);
7829                    if (targetUid > 0) {
7830                        if (needed == null) {
7831                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7832                        }
7833                        needed.add(grantUri);
7834                    }
7835                } else {
7836                    Intent clipIntent = clip.getItemAt(i).getIntent();
7837                    if (clipIntent != null) {
7838                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7839                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7840                        if (newNeeded != null) {
7841                            needed = newNeeded;
7842                        }
7843                    }
7844                }
7845            }
7846        }
7847
7848        return needed;
7849    }
7850
7851    /**
7852     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7853     */
7854    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7855            UriPermissionOwner owner) {
7856        if (needed != null) {
7857            for (int i=0; i<needed.size(); i++) {
7858                GrantUri grantUri = needed.get(i);
7859                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7860                        grantUri, needed.flags, owner);
7861            }
7862        }
7863    }
7864
7865    void grantUriPermissionFromIntentLocked(int callingUid,
7866            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7867        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7868                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7869        if (needed == null) {
7870            return;
7871        }
7872
7873        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7874    }
7875
7876    /**
7877     * @param uri This uri must NOT contain an embedded userId.
7878     * @param userId The userId in which the uri is to be resolved.
7879     */
7880    @Override
7881    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7882            final int modeFlags, int userId) {
7883        enforceNotIsolatedCaller("grantUriPermission");
7884        GrantUri grantUri = new GrantUri(userId, uri, false);
7885        synchronized(this) {
7886            final ProcessRecord r = getRecordForAppLocked(caller);
7887            if (r == null) {
7888                throw new SecurityException("Unable to find app for caller "
7889                        + caller
7890                        + " when granting permission to uri " + grantUri);
7891            }
7892            if (targetPkg == null) {
7893                throw new IllegalArgumentException("null target");
7894            }
7895            if (grantUri == null) {
7896                throw new IllegalArgumentException("null uri");
7897            }
7898
7899            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7900                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7901                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7902                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7903
7904            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7905                    UserHandle.getUserId(r.uid));
7906        }
7907    }
7908
7909    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7910        if (perm.modeFlags == 0) {
7911            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7912                    perm.targetUid);
7913            if (perms != null) {
7914                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7915                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7916
7917                perms.remove(perm.uri);
7918                if (perms.isEmpty()) {
7919                    mGrantedUriPermissions.remove(perm.targetUid);
7920                }
7921            }
7922        }
7923    }
7924
7925    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7926        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7927                "Revoking all granted permissions to " + grantUri);
7928
7929        final IPackageManager pm = AppGlobals.getPackageManager();
7930        final String authority = grantUri.uri.getAuthority();
7931        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7932        if (pi == null) {
7933            Slog.w(TAG, "No content provider found for permission revoke: "
7934                    + grantUri.toSafeString());
7935            return;
7936        }
7937
7938        // Does the caller have this permission on the URI?
7939        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7940            // If they don't have direct access to the URI, then revoke any
7941            // ownerless URI permissions that have been granted to them.
7942            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7943            if (perms != null) {
7944                boolean persistChanged = false;
7945                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7946                    final UriPermission perm = it.next();
7947                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7948                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7949                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7950                                "Revoking non-owned " + perm.targetUid
7951                                + " permission to " + perm.uri);
7952                        persistChanged |= perm.revokeModes(
7953                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7954                        if (perm.modeFlags == 0) {
7955                            it.remove();
7956                        }
7957                    }
7958                }
7959                if (perms.isEmpty()) {
7960                    mGrantedUriPermissions.remove(callingUid);
7961                }
7962                if (persistChanged) {
7963                    schedulePersistUriGrants();
7964                }
7965            }
7966            return;
7967        }
7968
7969        boolean persistChanged = false;
7970
7971        // Go through all of the permissions and remove any that match.
7972        int N = mGrantedUriPermissions.size();
7973        for (int i = 0; i < N; i++) {
7974            final int targetUid = mGrantedUriPermissions.keyAt(i);
7975            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7976
7977            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7978                final UriPermission perm = it.next();
7979                if (perm.uri.sourceUserId == grantUri.sourceUserId
7980                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7981                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7983                    persistChanged |= perm.revokeModes(
7984                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7985                    if (perm.modeFlags == 0) {
7986                        it.remove();
7987                    }
7988                }
7989            }
7990
7991            if (perms.isEmpty()) {
7992                mGrantedUriPermissions.remove(targetUid);
7993                N--;
7994                i--;
7995            }
7996        }
7997
7998        if (persistChanged) {
7999            schedulePersistUriGrants();
8000        }
8001    }
8002
8003    /**
8004     * @param uri This uri must NOT contain an embedded userId.
8005     * @param userId The userId in which the uri is to be resolved.
8006     */
8007    @Override
8008    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8009            int userId) {
8010        enforceNotIsolatedCaller("revokeUriPermission");
8011        synchronized(this) {
8012            final ProcessRecord r = getRecordForAppLocked(caller);
8013            if (r == null) {
8014                throw new SecurityException("Unable to find app for caller "
8015                        + caller
8016                        + " when revoking permission to uri " + uri);
8017            }
8018            if (uri == null) {
8019                Slog.w(TAG, "revokeUriPermission: null uri");
8020                return;
8021            }
8022
8023            if (!Intent.isAccessUriMode(modeFlags)) {
8024                return;
8025            }
8026
8027            final String authority = uri.getAuthority();
8028            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8029            if (pi == null) {
8030                Slog.w(TAG, "No content provider found for permission revoke: "
8031                        + uri.toSafeString());
8032                return;
8033            }
8034
8035            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8036        }
8037    }
8038
8039    /**
8040     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8041     * given package.
8042     *
8043     * @param packageName Package name to match, or {@code null} to apply to all
8044     *            packages.
8045     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8046     *            to all users.
8047     * @param persistable If persistable grants should be removed.
8048     */
8049    private void removeUriPermissionsForPackageLocked(
8050            String packageName, int userHandle, boolean persistable) {
8051        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8052            throw new IllegalArgumentException("Must narrow by either package or user");
8053        }
8054
8055        boolean persistChanged = false;
8056
8057        int N = mGrantedUriPermissions.size();
8058        for (int i = 0; i < N; i++) {
8059            final int targetUid = mGrantedUriPermissions.keyAt(i);
8060            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8061
8062            // Only inspect grants matching user
8063            if (userHandle == UserHandle.USER_ALL
8064                    || userHandle == UserHandle.getUserId(targetUid)) {
8065                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8066                    final UriPermission perm = it.next();
8067
8068                    // Only inspect grants matching package
8069                    if (packageName == null || perm.sourcePkg.equals(packageName)
8070                            || perm.targetPkg.equals(packageName)) {
8071                        persistChanged |= perm.revokeModes(persistable
8072                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8073
8074                        // Only remove when no modes remain; any persisted grants
8075                        // will keep this alive.
8076                        if (perm.modeFlags == 0) {
8077                            it.remove();
8078                        }
8079                    }
8080                }
8081
8082                if (perms.isEmpty()) {
8083                    mGrantedUriPermissions.remove(targetUid);
8084                    N--;
8085                    i--;
8086                }
8087            }
8088        }
8089
8090        if (persistChanged) {
8091            schedulePersistUriGrants();
8092        }
8093    }
8094
8095    @Override
8096    public IBinder newUriPermissionOwner(String name) {
8097        enforceNotIsolatedCaller("newUriPermissionOwner");
8098        synchronized(this) {
8099            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8100            return owner.getExternalTokenLocked();
8101        }
8102    }
8103
8104    @Override
8105    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8106        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8107        synchronized(this) {
8108            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8109            if (r == null) {
8110                throw new IllegalArgumentException("Activity does not exist; token="
8111                        + activityToken);
8112            }
8113            return r.getUriPermissionsLocked().getExternalTokenLocked();
8114        }
8115    }
8116    /**
8117     * @param uri This uri must NOT contain an embedded userId.
8118     * @param sourceUserId The userId in which the uri is to be resolved.
8119     * @param targetUserId The userId of the app that receives the grant.
8120     */
8121    @Override
8122    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8123            final int modeFlags, int sourceUserId, int targetUserId) {
8124        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8125                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8126                "grantUriPermissionFromOwner", null);
8127        synchronized(this) {
8128            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8129            if (owner == null) {
8130                throw new IllegalArgumentException("Unknown owner: " + token);
8131            }
8132            if (fromUid != Binder.getCallingUid()) {
8133                if (Binder.getCallingUid() != Process.myUid()) {
8134                    // Only system code can grant URI permissions on behalf
8135                    // of other users.
8136                    throw new SecurityException("nice try");
8137                }
8138            }
8139            if (targetPkg == null) {
8140                throw new IllegalArgumentException("null target");
8141            }
8142            if (uri == null) {
8143                throw new IllegalArgumentException("null uri");
8144            }
8145
8146            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8147                    modeFlags, owner, targetUserId);
8148        }
8149    }
8150
8151    /**
8152     * @param uri This uri must NOT contain an embedded userId.
8153     * @param userId The userId in which the uri is to be resolved.
8154     */
8155    @Override
8156    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8157        synchronized(this) {
8158            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8159            if (owner == null) {
8160                throw new IllegalArgumentException("Unknown owner: " + token);
8161            }
8162
8163            if (uri == null) {
8164                owner.removeUriPermissionsLocked(mode);
8165            } else {
8166                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8167            }
8168        }
8169    }
8170
8171    private void schedulePersistUriGrants() {
8172        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8173            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8174                    10 * DateUtils.SECOND_IN_MILLIS);
8175        }
8176    }
8177
8178    private void writeGrantedUriPermissions() {
8179        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8180
8181        // Snapshot permissions so we can persist without lock
8182        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8183        synchronized (this) {
8184            final int size = mGrantedUriPermissions.size();
8185            for (int i = 0; i < size; i++) {
8186                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8187                for (UriPermission perm : perms.values()) {
8188                    if (perm.persistedModeFlags != 0) {
8189                        persist.add(perm.snapshot());
8190                    }
8191                }
8192            }
8193        }
8194
8195        FileOutputStream fos = null;
8196        try {
8197            fos = mGrantFile.startWrite();
8198
8199            XmlSerializer out = new FastXmlSerializer();
8200            out.setOutput(fos, StandardCharsets.UTF_8.name());
8201            out.startDocument(null, true);
8202            out.startTag(null, TAG_URI_GRANTS);
8203            for (UriPermission.Snapshot perm : persist) {
8204                out.startTag(null, TAG_URI_GRANT);
8205                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8206                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8207                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8208                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8209                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8210                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8211                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8212                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8213                out.endTag(null, TAG_URI_GRANT);
8214            }
8215            out.endTag(null, TAG_URI_GRANTS);
8216            out.endDocument();
8217
8218            mGrantFile.finishWrite(fos);
8219        } catch (IOException e) {
8220            if (fos != null) {
8221                mGrantFile.failWrite(fos);
8222            }
8223        }
8224    }
8225
8226    private void readGrantedUriPermissionsLocked() {
8227        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8228
8229        final long now = System.currentTimeMillis();
8230
8231        FileInputStream fis = null;
8232        try {
8233            fis = mGrantFile.openRead();
8234            final XmlPullParser in = Xml.newPullParser();
8235            in.setInput(fis, StandardCharsets.UTF_8.name());
8236
8237            int type;
8238            while ((type = in.next()) != END_DOCUMENT) {
8239                final String tag = in.getName();
8240                if (type == START_TAG) {
8241                    if (TAG_URI_GRANT.equals(tag)) {
8242                        final int sourceUserId;
8243                        final int targetUserId;
8244                        final int userHandle = readIntAttribute(in,
8245                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8246                        if (userHandle != UserHandle.USER_NULL) {
8247                            // For backwards compatibility.
8248                            sourceUserId = userHandle;
8249                            targetUserId = userHandle;
8250                        } else {
8251                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8252                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8253                        }
8254                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8255                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8256                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8257                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8258                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8259                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8260
8261                        // Sanity check that provider still belongs to source package
8262                        final ProviderInfo pi = getProviderInfoLocked(
8263                                uri.getAuthority(), sourceUserId);
8264                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8265                            int targetUid = -1;
8266                            try {
8267                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8268                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8269                            } catch (RemoteException e) {
8270                            }
8271                            if (targetUid != -1) {
8272                                final UriPermission perm = findOrCreateUriPermissionLocked(
8273                                        sourcePkg, targetPkg, targetUid,
8274                                        new GrantUri(sourceUserId, uri, prefix));
8275                                perm.initPersistedModes(modeFlags, createdTime);
8276                            }
8277                        } else {
8278                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8279                                    + " but instead found " + pi);
8280                        }
8281                    }
8282                }
8283            }
8284        } catch (FileNotFoundException e) {
8285            // Missing grants is okay
8286        } catch (IOException e) {
8287            Slog.wtf(TAG, "Failed reading Uri grants", e);
8288        } catch (XmlPullParserException e) {
8289            Slog.wtf(TAG, "Failed reading Uri grants", e);
8290        } finally {
8291            IoUtils.closeQuietly(fis);
8292        }
8293    }
8294
8295    /**
8296     * @param uri This uri must NOT contain an embedded userId.
8297     * @param userId The userId in which the uri is to be resolved.
8298     */
8299    @Override
8300    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8301        enforceNotIsolatedCaller("takePersistableUriPermission");
8302
8303        Preconditions.checkFlagsArgument(modeFlags,
8304                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8305
8306        synchronized (this) {
8307            final int callingUid = Binder.getCallingUid();
8308            boolean persistChanged = false;
8309            GrantUri grantUri = new GrantUri(userId, uri, false);
8310
8311            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8312                    new GrantUri(userId, uri, false));
8313            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8314                    new GrantUri(userId, uri, true));
8315
8316            final boolean exactValid = (exactPerm != null)
8317                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8318            final boolean prefixValid = (prefixPerm != null)
8319                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8320
8321            if (!(exactValid || prefixValid)) {
8322                throw new SecurityException("No persistable permission grants found for UID "
8323                        + callingUid + " and Uri " + grantUri.toSafeString());
8324            }
8325
8326            if (exactValid) {
8327                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8328            }
8329            if (prefixValid) {
8330                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8331            }
8332
8333            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8334
8335            if (persistChanged) {
8336                schedulePersistUriGrants();
8337            }
8338        }
8339    }
8340
8341    /**
8342     * @param uri This uri must NOT contain an embedded userId.
8343     * @param userId The userId in which the uri is to be resolved.
8344     */
8345    @Override
8346    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8347        enforceNotIsolatedCaller("releasePersistableUriPermission");
8348
8349        Preconditions.checkFlagsArgument(modeFlags,
8350                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8351
8352        synchronized (this) {
8353            final int callingUid = Binder.getCallingUid();
8354            boolean persistChanged = false;
8355
8356            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8357                    new GrantUri(userId, uri, false));
8358            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8359                    new GrantUri(userId, uri, true));
8360            if (exactPerm == null && prefixPerm == null) {
8361                throw new SecurityException("No permission grants found for UID " + callingUid
8362                        + " and Uri " + uri.toSafeString());
8363            }
8364
8365            if (exactPerm != null) {
8366                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8367                removeUriPermissionIfNeededLocked(exactPerm);
8368            }
8369            if (prefixPerm != null) {
8370                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8371                removeUriPermissionIfNeededLocked(prefixPerm);
8372            }
8373
8374            if (persistChanged) {
8375                schedulePersistUriGrants();
8376            }
8377        }
8378    }
8379
8380    /**
8381     * Prune any older {@link UriPermission} for the given UID until outstanding
8382     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8383     *
8384     * @return if any mutations occured that require persisting.
8385     */
8386    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8387        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8388        if (perms == null) return false;
8389        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8390
8391        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8392        for (UriPermission perm : perms.values()) {
8393            if (perm.persistedModeFlags != 0) {
8394                persisted.add(perm);
8395            }
8396        }
8397
8398        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8399        if (trimCount <= 0) return false;
8400
8401        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8402        for (int i = 0; i < trimCount; i++) {
8403            final UriPermission perm = persisted.get(i);
8404
8405            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8406                    "Trimming grant created at " + perm.persistedCreateTime);
8407
8408            perm.releasePersistableModes(~0);
8409            removeUriPermissionIfNeededLocked(perm);
8410        }
8411
8412        return true;
8413    }
8414
8415    @Override
8416    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8417            String packageName, boolean incoming) {
8418        enforceNotIsolatedCaller("getPersistedUriPermissions");
8419        Preconditions.checkNotNull(packageName, "packageName");
8420
8421        final int callingUid = Binder.getCallingUid();
8422        final IPackageManager pm = AppGlobals.getPackageManager();
8423        try {
8424            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8425                    UserHandle.getUserId(callingUid));
8426            if (packageUid != callingUid) {
8427                throw new SecurityException(
8428                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8429            }
8430        } catch (RemoteException e) {
8431            throw new SecurityException("Failed to verify package name ownership");
8432        }
8433
8434        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8435        synchronized (this) {
8436            if (incoming) {
8437                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8438                        callingUid);
8439                if (perms == null) {
8440                    Slog.w(TAG, "No permission grants found for " + packageName);
8441                } else {
8442                    for (UriPermission perm : perms.values()) {
8443                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8444                            result.add(perm.buildPersistedPublicApiObject());
8445                        }
8446                    }
8447                }
8448            } else {
8449                final int size = mGrantedUriPermissions.size();
8450                for (int i = 0; i < size; i++) {
8451                    final ArrayMap<GrantUri, UriPermission> perms =
8452                            mGrantedUriPermissions.valueAt(i);
8453                    for (UriPermission perm : perms.values()) {
8454                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8455                            result.add(perm.buildPersistedPublicApiObject());
8456                        }
8457                    }
8458                }
8459            }
8460        }
8461        return new ParceledListSlice<android.content.UriPermission>(result);
8462    }
8463
8464    @Override
8465    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8466            String packageName, int userId) {
8467        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8468                "getGrantedUriPermissions");
8469
8470        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8471        synchronized (this) {
8472            final int size = mGrantedUriPermissions.size();
8473            for (int i = 0; i < size; i++) {
8474                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8475                for (UriPermission perm : perms.values()) {
8476                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8477                            && perm.persistedModeFlags != 0) {
8478                        result.add(perm.buildPersistedPublicApiObject());
8479                    }
8480                }
8481            }
8482        }
8483        return new ParceledListSlice<android.content.UriPermission>(result);
8484    }
8485
8486    @Override
8487    public void clearGrantedUriPermissions(String packageName, int userId) {
8488        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8489                "clearGrantedUriPermissions");
8490        removeUriPermissionsForPackageLocked(packageName, userId, true);
8491    }
8492
8493    @Override
8494    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8495        synchronized (this) {
8496            ProcessRecord app =
8497                who != null ? getRecordForAppLocked(who) : null;
8498            if (app == null) return;
8499
8500            Message msg = Message.obtain();
8501            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8502            msg.obj = app;
8503            msg.arg1 = waiting ? 1 : 0;
8504            mUiHandler.sendMessage(msg);
8505        }
8506    }
8507
8508    @Override
8509    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8510        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8511        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8512        outInfo.availMem = Process.getFreeMemory();
8513        outInfo.totalMem = Process.getTotalMemory();
8514        outInfo.threshold = homeAppMem;
8515        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8516        outInfo.hiddenAppThreshold = cachedAppMem;
8517        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8518                ProcessList.SERVICE_ADJ);
8519        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8520                ProcessList.VISIBLE_APP_ADJ);
8521        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8522                ProcessList.FOREGROUND_APP_ADJ);
8523    }
8524
8525    // =========================================================
8526    // TASK MANAGEMENT
8527    // =========================================================
8528
8529    @Override
8530    public List<IAppTask> getAppTasks(String callingPackage) {
8531        int callingUid = Binder.getCallingUid();
8532        long ident = Binder.clearCallingIdentity();
8533
8534        synchronized(this) {
8535            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8536            try {
8537                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8538
8539                final int N = mRecentTasks.size();
8540                for (int i = 0; i < N; i++) {
8541                    TaskRecord tr = mRecentTasks.get(i);
8542                    // Skip tasks that do not match the caller.  We don't need to verify
8543                    // callingPackage, because we are also limiting to callingUid and know
8544                    // that will limit to the correct security sandbox.
8545                    if (tr.effectiveUid != callingUid) {
8546                        continue;
8547                    }
8548                    Intent intent = tr.getBaseIntent();
8549                    if (intent == null ||
8550                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8551                        continue;
8552                    }
8553                    ActivityManager.RecentTaskInfo taskInfo =
8554                            createRecentTaskInfoFromTaskRecord(tr);
8555                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8556                    list.add(taskImpl);
8557                }
8558            } finally {
8559                Binder.restoreCallingIdentity(ident);
8560            }
8561            return list;
8562        }
8563    }
8564
8565    @Override
8566    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8567        final int callingUid = Binder.getCallingUid();
8568        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8569
8570        synchronized(this) {
8571            if (DEBUG_ALL) Slog.v(
8572                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8573
8574            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8575                    callingUid);
8576
8577            // TODO: Improve with MRU list from all ActivityStacks.
8578            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8579        }
8580
8581        return list;
8582    }
8583
8584    /**
8585     * Creates a new RecentTaskInfo from a TaskRecord.
8586     */
8587    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8588        // Update the task description to reflect any changes in the task stack
8589        tr.updateTaskDescription();
8590
8591        // Compose the recent task info
8592        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8593        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8594        rti.persistentId = tr.taskId;
8595        rti.baseIntent = new Intent(tr.getBaseIntent());
8596        rti.origActivity = tr.origActivity;
8597        rti.realActivity = tr.realActivity;
8598        rti.description = tr.lastDescription;
8599        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8600        rti.userId = tr.userId;
8601        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8602        rti.firstActiveTime = tr.firstActiveTime;
8603        rti.lastActiveTime = tr.lastActiveTime;
8604        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8605        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8606        rti.numActivities = 0;
8607        if (tr.mBounds != null) {
8608            rti.bounds = new Rect(tr.mBounds);
8609        }
8610        rti.isDockable = tr.canGoInDockedStack();
8611
8612        ActivityRecord base = null;
8613        ActivityRecord top = null;
8614        ActivityRecord tmp;
8615
8616        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8617            tmp = tr.mActivities.get(i);
8618            if (tmp.finishing) {
8619                continue;
8620            }
8621            base = tmp;
8622            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8623                top = base;
8624            }
8625            rti.numActivities++;
8626        }
8627
8628        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8629        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8630
8631        return rti;
8632    }
8633
8634    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8635        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8636                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8637        if (!allowed) {
8638            if (checkPermission(android.Manifest.permission.GET_TASKS,
8639                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8640                // Temporary compatibility: some existing apps on the system image may
8641                // still be requesting the old permission and not switched to the new
8642                // one; if so, we'll still allow them full access.  This means we need
8643                // to see if they are holding the old permission and are a system app.
8644                try {
8645                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8646                        allowed = true;
8647                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8648                                + " is using old GET_TASKS but privileged; allowing");
8649                    }
8650                } catch (RemoteException e) {
8651                }
8652            }
8653        }
8654        if (!allowed) {
8655            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8656                    + " does not hold REAL_GET_TASKS; limiting output");
8657        }
8658        return allowed;
8659    }
8660
8661    @Override
8662    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8663        final int callingUid = Binder.getCallingUid();
8664        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8665                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8666
8667        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8668        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8669        synchronized (this) {
8670            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8671                    callingUid);
8672            final boolean detailed = checkCallingPermission(
8673                    android.Manifest.permission.GET_DETAILED_TASKS)
8674                    == PackageManager.PERMISSION_GRANTED;
8675
8676            mRecentTasks.loadUserRecentsLocked(userId);
8677
8678            final int recentsCount = mRecentTasks.size();
8679            ArrayList<ActivityManager.RecentTaskInfo> res =
8680                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8681
8682            final Set<Integer> includedUsers;
8683            if (includeProfiles) {
8684                includedUsers = mUserController.getProfileIds(userId);
8685            } else {
8686                includedUsers = new HashSet<>();
8687            }
8688            includedUsers.add(Integer.valueOf(userId));
8689
8690            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8691                TaskRecord tr = mRecentTasks.get(i);
8692                // Only add calling user or related users recent tasks
8693                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8694                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8695                    continue;
8696                }
8697
8698                if (tr.realActivitySuspended) {
8699                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8700                    continue;
8701                }
8702
8703                // Return the entry if desired by the caller.  We always return
8704                // the first entry, because callers always expect this to be the
8705                // foreground app.  We may filter others if the caller has
8706                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8707                // we should exclude the entry.
8708
8709                if (i == 0
8710                        || withExcluded
8711                        || (tr.intent == null)
8712                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8713                                == 0)) {
8714                    if (!allowed) {
8715                        // If the caller doesn't have the GET_TASKS permission, then only
8716                        // allow them to see a small subset of tasks -- their own and home.
8717                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8718                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8719                            continue;
8720                        }
8721                    }
8722                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8723                        if (tr.stack != null && tr.stack.isHomeStack()) {
8724                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8725                                    "Skipping, home stack task: " + tr);
8726                            continue;
8727                        }
8728                    }
8729                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8730                        if (tr.stack != null && tr.stack.isDockedStack()) {
8731                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8732                                    "Skipping, docked stack task: " + tr);
8733                            continue;
8734                        }
8735                    }
8736                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8737                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8738                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8739                                    "Skipping, pinned stack task: " + tr);
8740                            continue;
8741                        }
8742                    }
8743                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8744                        // Don't include auto remove tasks that are finished or finishing.
8745                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8746                                "Skipping, auto-remove without activity: " + tr);
8747                        continue;
8748                    }
8749                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8750                            && !tr.isAvailable) {
8751                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8752                                "Skipping, unavail real act: " + tr);
8753                        continue;
8754                    }
8755
8756                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8757                    if (!detailed) {
8758                        rti.baseIntent.replaceExtras((Bundle)null);
8759                    }
8760
8761                    res.add(rti);
8762                    maxNum--;
8763                }
8764            }
8765            return res;
8766        }
8767    }
8768
8769    @Override
8770    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8771        synchronized (this) {
8772            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8773                    "getTaskThumbnail()");
8774            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8775                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8776            if (tr != null) {
8777                return tr.getTaskThumbnailLocked();
8778            }
8779        }
8780        return null;
8781    }
8782
8783    @Override
8784    public int addAppTask(IBinder activityToken, Intent intent,
8785            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8786        final int callingUid = Binder.getCallingUid();
8787        final long callingIdent = Binder.clearCallingIdentity();
8788
8789        try {
8790            synchronized (this) {
8791                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8792                if (r == null) {
8793                    throw new IllegalArgumentException("Activity does not exist; token="
8794                            + activityToken);
8795                }
8796                ComponentName comp = intent.getComponent();
8797                if (comp == null) {
8798                    throw new IllegalArgumentException("Intent " + intent
8799                            + " must specify explicit component");
8800                }
8801                if (thumbnail.getWidth() != mThumbnailWidth
8802                        || thumbnail.getHeight() != mThumbnailHeight) {
8803                    throw new IllegalArgumentException("Bad thumbnail size: got "
8804                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8805                            + mThumbnailWidth + "x" + mThumbnailHeight);
8806                }
8807                if (intent.getSelector() != null) {
8808                    intent.setSelector(null);
8809                }
8810                if (intent.getSourceBounds() != null) {
8811                    intent.setSourceBounds(null);
8812                }
8813                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8814                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8815                        // The caller has added this as an auto-remove task...  that makes no
8816                        // sense, so turn off auto-remove.
8817                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8818                    }
8819                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8820                    // Must be a new task.
8821                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8822                }
8823                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8824                    mLastAddedTaskActivity = null;
8825                }
8826                ActivityInfo ainfo = mLastAddedTaskActivity;
8827                if (ainfo == null) {
8828                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8829                            comp, 0, UserHandle.getUserId(callingUid));
8830                    if (ainfo.applicationInfo.uid != callingUid) {
8831                        throw new SecurityException(
8832                                "Can't add task for another application: target uid="
8833                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8834                    }
8835                }
8836
8837                // Use the full screen as the context for the task thumbnail
8838                final Point displaySize = new Point();
8839                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8840                r.task.stack.getDisplaySize(displaySize);
8841                thumbnailInfo.taskWidth = displaySize.x;
8842                thumbnailInfo.taskHeight = displaySize.y;
8843                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8844
8845                TaskRecord task = new TaskRecord(this,
8846                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
8847                        ainfo, intent, description, thumbnailInfo);
8848
8849                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8850                if (trimIdx >= 0) {
8851                    // If this would have caused a trim, then we'll abort because that
8852                    // means it would be added at the end of the list but then just removed.
8853                    return INVALID_TASK_ID;
8854                }
8855
8856                final int N = mRecentTasks.size();
8857                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8858                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8859                    tr.removedFromRecents();
8860                }
8861
8862                task.inRecents = true;
8863                mRecentTasks.add(task);
8864                r.task.stack.addTask(task, false, "addAppTask");
8865
8866                task.setLastThumbnailLocked(thumbnail);
8867                task.freeLastThumbnail();
8868
8869                return task.taskId;
8870            }
8871        } finally {
8872            Binder.restoreCallingIdentity(callingIdent);
8873        }
8874    }
8875
8876    @Override
8877    public Point getAppTaskThumbnailSize() {
8878        synchronized (this) {
8879            return new Point(mThumbnailWidth,  mThumbnailHeight);
8880        }
8881    }
8882
8883    @Override
8884    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8885        synchronized (this) {
8886            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8887            if (r != null) {
8888                r.setTaskDescription(td);
8889                r.task.updateTaskDescription();
8890            }
8891        }
8892    }
8893
8894    @Override
8895    public void setTaskResizeable(int taskId, int resizeableMode) {
8896        synchronized (this) {
8897            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8898                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8899            if (task == null) {
8900                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8901                return;
8902            }
8903            if (task.mResizeMode != resizeableMode) {
8904                task.mResizeMode = resizeableMode;
8905                mWindowManager.setTaskResizeable(taskId, resizeableMode);
8906                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8907                mStackSupervisor.resumeFocusedStackTopActivityLocked();
8908            }
8909        }
8910    }
8911
8912    @Override
8913    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8914        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
8915        long ident = Binder.clearCallingIdentity();
8916        try {
8917            synchronized (this) {
8918                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8919                if (task == null) {
8920                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8921                    return;
8922                }
8923                int stackId = task.stack.mStackId;
8924                // We allow the task to scroll instead of resizing if this is a non-resizeable task
8925                // in crop windows resize mode or if the task size is affected by the docked stack
8926                // changing size. No need to update configuration.
8927                if (bounds != null && task.inCropWindowsResizeMode()
8928                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
8929                    mWindowManager.scrollTask(task.taskId, bounds);
8930                    return;
8931                }
8932
8933                // Place the task in the right stack if it isn't there already based on
8934                // the requested bounds.
8935                // The stack transition logic is:
8936                // - a null bounds on a freeform task moves that task to fullscreen
8937                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8938                //   that task to freeform
8939                // - otherwise the task is not moved
8940                if (!StackId.isTaskResizeAllowed(stackId)) {
8941                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8942                }
8943                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8944                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8945                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8946                    stackId = FREEFORM_WORKSPACE_STACK_ID;
8947                }
8948                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8949                if (stackId != task.stack.mStackId) {
8950                    mStackSupervisor.moveTaskToStackUncheckedLocked(
8951                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8952                    preserveWindow = false;
8953                }
8954
8955                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8956            }
8957        } finally {
8958            Binder.restoreCallingIdentity(ident);
8959        }
8960    }
8961
8962    @Override
8963    public Rect getTaskBounds(int taskId) {
8964        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
8965        long ident = Binder.clearCallingIdentity();
8966        Rect rect = new Rect();
8967        try {
8968            synchronized (this) {
8969                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8970                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8971                if (task == null) {
8972                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8973                    return rect;
8974                }
8975                if (task.stack != null) {
8976                    // Return the bounds from window manager since it will be adjusted for various
8977                    // things like the presense of a docked stack for tasks that aren't resizeable.
8978                    mWindowManager.getTaskBounds(task.taskId, rect);
8979                } else {
8980                    // Task isn't in window manager yet since it isn't associated with a stack.
8981                    // Return the persist value from activity manager
8982                    if (task.mBounds != null) {
8983                        rect.set(task.mBounds);
8984                    } else if (task.mLastNonFullscreenBounds != null) {
8985                        rect.set(task.mLastNonFullscreenBounds);
8986                    }
8987                }
8988            }
8989        } finally {
8990            Binder.restoreCallingIdentity(ident);
8991        }
8992        return rect;
8993    }
8994
8995    @Override
8996    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
8997        if (userId != UserHandle.getCallingUserId()) {
8998            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8999                    "getTaskDescriptionIcon");
9000        }
9001        final File passedIconFile = new File(filePath);
9002        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9003                passedIconFile.getName());
9004        if (!legitIconFile.getPath().equals(filePath)
9005                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9006            throw new IllegalArgumentException("Bad file path: " + filePath
9007                    + " passed for userId " + userId);
9008        }
9009        return mRecentTasks.getTaskDescriptionIcon(filePath);
9010    }
9011
9012    @Override
9013    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9014            throws RemoteException {
9015        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9016                opts.getCustomInPlaceResId() == 0) {
9017            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9018                    "with valid animation");
9019        }
9020        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9021        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9022                opts.getCustomInPlaceResId());
9023        mWindowManager.executeAppTransition();
9024    }
9025
9026    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9027            boolean removeFromRecents) {
9028        if (removeFromRecents) {
9029            mRecentTasks.remove(tr);
9030            tr.removedFromRecents();
9031        }
9032        ComponentName component = tr.getBaseIntent().getComponent();
9033        if (component == null) {
9034            Slog.w(TAG, "No component for base intent of task: " + tr);
9035            return;
9036        }
9037
9038        // Find any running services associated with this app and stop if needed.
9039        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9040
9041        if (!killProcess) {
9042            return;
9043        }
9044
9045        // Determine if the process(es) for this task should be killed.
9046        final String pkg = component.getPackageName();
9047        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9048        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9049        for (int i = 0; i < pmap.size(); i++) {
9050
9051            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9052            for (int j = 0; j < uids.size(); j++) {
9053                ProcessRecord proc = uids.valueAt(j);
9054                if (proc.userId != tr.userId) {
9055                    // Don't kill process for a different user.
9056                    continue;
9057                }
9058                if (proc == mHomeProcess) {
9059                    // Don't kill the home process along with tasks from the same package.
9060                    continue;
9061                }
9062                if (!proc.pkgList.containsKey(pkg)) {
9063                    // Don't kill process that is not associated with this task.
9064                    continue;
9065                }
9066
9067                for (int k = 0; k < proc.activities.size(); k++) {
9068                    TaskRecord otherTask = proc.activities.get(k).task;
9069                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9070                        // Don't kill process(es) that has an activity in a different task that is
9071                        // also in recents.
9072                        return;
9073                    }
9074                }
9075
9076                if (proc.foregroundServices) {
9077                    // Don't kill process(es) with foreground service.
9078                    return;
9079                }
9080
9081                // Add process to kill list.
9082                procsToKill.add(proc);
9083            }
9084        }
9085
9086        // Kill the running processes.
9087        for (int i = 0; i < procsToKill.size(); i++) {
9088            ProcessRecord pr = procsToKill.get(i);
9089            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9090                    && pr.curReceiver == null) {
9091                pr.kill("remove task", true);
9092            } else {
9093                // We delay killing processes that are not in the background or running a receiver.
9094                pr.waitingToKill = "remove task";
9095            }
9096        }
9097    }
9098
9099    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9100        // Remove all tasks with activities in the specified package from the list of recent tasks
9101        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9102            TaskRecord tr = mRecentTasks.get(i);
9103            if (tr.userId != userId) continue;
9104
9105            ComponentName cn = tr.intent.getComponent();
9106            if (cn != null && cn.getPackageName().equals(packageName)) {
9107                // If the package name matches, remove the task.
9108                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9109            }
9110        }
9111    }
9112
9113    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9114            int userId) {
9115
9116        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9117            TaskRecord tr = mRecentTasks.get(i);
9118            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9119                continue;
9120            }
9121
9122            ComponentName cn = tr.intent.getComponent();
9123            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9124                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9125            if (sameComponent) {
9126                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9127            }
9128        }
9129    }
9130
9131    /**
9132     * Removes the task with the specified task id.
9133     *
9134     * @param taskId Identifier of the task to be removed.
9135     * @param killProcess Kill any process associated with the task if possible.
9136     * @param removeFromRecents Whether to also remove the task from recents.
9137     * @return Returns true if the given task was found and removed.
9138     */
9139    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9140            boolean removeFromRecents) {
9141        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9142                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9143        if (tr != null) {
9144            tr.removeTaskActivitiesLocked();
9145            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9146            if (tr.isPersistable) {
9147                notifyTaskPersisterLocked(null, true);
9148            }
9149            return true;
9150        }
9151        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9152        return false;
9153    }
9154
9155    @Override
9156    public boolean removeTask(int taskId) {
9157        synchronized (this) {
9158            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9159                    "removeTask()");
9160            long ident = Binder.clearCallingIdentity();
9161            try {
9162                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9163            } finally {
9164                Binder.restoreCallingIdentity(ident);
9165            }
9166        }
9167    }
9168
9169    /**
9170     * TODO: Add mController hook
9171     */
9172    @Override
9173    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9174        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9175
9176        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9177        synchronized(this) {
9178            moveTaskToFrontLocked(taskId, flags, bOptions);
9179        }
9180    }
9181
9182    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9183        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9184
9185        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9186                Binder.getCallingUid(), -1, -1, "Task to front")) {
9187            ActivityOptions.abort(options);
9188            return;
9189        }
9190        final long origId = Binder.clearCallingIdentity();
9191        try {
9192            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9193            if (task == null) {
9194                Slog.d(TAG, "Could not find task for id: "+ taskId);
9195                return;
9196            }
9197            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9198                mStackSupervisor.showLockTaskToast();
9199                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9200                return;
9201            }
9202            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9203            if (prev != null && prev.isRecentsActivity()) {
9204                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9205            }
9206            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9207        } finally {
9208            Binder.restoreCallingIdentity(origId);
9209        }
9210        ActivityOptions.abort(options);
9211    }
9212
9213    /**
9214     * Moves an activity, and all of the other activities within the same task, to the bottom
9215     * of the history stack.  The activity's order within the task is unchanged.
9216     *
9217     * @param token A reference to the activity we wish to move
9218     * @param nonRoot If false then this only works if the activity is the root
9219     *                of a task; if true it will work for any activity in a task.
9220     * @return Returns true if the move completed, false if not.
9221     */
9222    @Override
9223    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9224        enforceNotIsolatedCaller("moveActivityTaskToBack");
9225        synchronized(this) {
9226            final long origId = Binder.clearCallingIdentity();
9227            try {
9228                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9229                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9230                if (task != null) {
9231                    if (mStackSupervisor.isLockedTask(task)) {
9232                        mStackSupervisor.showLockTaskToast();
9233                        return false;
9234                    }
9235                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9236                }
9237            } finally {
9238                Binder.restoreCallingIdentity(origId);
9239            }
9240        }
9241        return false;
9242    }
9243
9244    @Override
9245    public void moveTaskBackwards(int task) {
9246        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9247                "moveTaskBackwards()");
9248
9249        synchronized(this) {
9250            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9251                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9252                return;
9253            }
9254            final long origId = Binder.clearCallingIdentity();
9255            moveTaskBackwardsLocked(task);
9256            Binder.restoreCallingIdentity(origId);
9257        }
9258    }
9259
9260    private final void moveTaskBackwardsLocked(int task) {
9261        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9262    }
9263
9264    @Override
9265    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9266            IActivityContainerCallback callback) throws RemoteException {
9267        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9268        synchronized (this) {
9269            if (parentActivityToken == null) {
9270                throw new IllegalArgumentException("parent token must not be null");
9271            }
9272            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9273            if (r == null) {
9274                return null;
9275            }
9276            if (callback == null) {
9277                throw new IllegalArgumentException("callback must not be null");
9278            }
9279            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9280        }
9281    }
9282
9283    @Override
9284    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9285        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9286        synchronized (this) {
9287            mStackSupervisor.deleteActivityContainer(container);
9288        }
9289    }
9290
9291    @Override
9292    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9293        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9294        synchronized (this) {
9295            final int stackId = mStackSupervisor.getNextStackId();
9296            final ActivityStack stack =
9297                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9298            if (stack == null) {
9299                return null;
9300            }
9301            return stack.mActivityContainer;
9302        }
9303    }
9304
9305    @Override
9306    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9307        synchronized (this) {
9308            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9309            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9310                return stack.mActivityContainer.getDisplayId();
9311            }
9312            return Display.DEFAULT_DISPLAY;
9313        }
9314    }
9315
9316    @Override
9317    public int getActivityStackId(IBinder token) throws RemoteException {
9318        synchronized (this) {
9319            ActivityStack stack = ActivityRecord.getStackLocked(token);
9320            if (stack == null) {
9321                return INVALID_STACK_ID;
9322            }
9323            return stack.mStackId;
9324        }
9325    }
9326
9327    @Override
9328    public void exitFreeformMode(IBinder token) throws RemoteException {
9329        synchronized (this) {
9330            long ident = Binder.clearCallingIdentity();
9331            try {
9332                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9333                if (r == null) {
9334                    throw new IllegalArgumentException(
9335                            "exitFreeformMode: No activity record matching token=" + token);
9336                }
9337                final ActivityStack stack = r.getStackLocked(token);
9338                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9339                    throw new IllegalStateException(
9340                            "exitFreeformMode: You can only go fullscreen from freeform.");
9341                }
9342                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9343                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9344                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9345            } finally {
9346                Binder.restoreCallingIdentity(ident);
9347            }
9348        }
9349    }
9350
9351    @Override
9352    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9353        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9354        if (stackId == HOME_STACK_ID) {
9355            throw new IllegalArgumentException(
9356                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9357        }
9358        synchronized (this) {
9359            long ident = Binder.clearCallingIdentity();
9360            try {
9361                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9362                        + " to stackId=" + stackId + " toTop=" + toTop);
9363                if (stackId == DOCKED_STACK_ID) {
9364                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9365                            null /* initialBounds */);
9366                }
9367                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9368                        "moveTaskToStack", ANIMATE);
9369            } finally {
9370                Binder.restoreCallingIdentity(ident);
9371            }
9372        }
9373    }
9374
9375    /**
9376     * Moves the input task to the docked stack.
9377     *
9378     * @param taskId Id of task to move.
9379     * @param createMode The mode the docked stack should be created in if it doesn't exist
9380     *                   already. See
9381     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9382     *                   and
9383     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9384     * @param toTop If the task and stack should be moved to the top.
9385     * @param animate Whether we should play an animation for the moving the task
9386     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9387     *                      docked stack. Pass {@code null} to use default bounds.
9388     */
9389    @Override
9390    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9391            Rect initialBounds) {
9392        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9393        synchronized (this) {
9394            long ident = Binder.clearCallingIdentity();
9395            try {
9396                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9397                        + " to createMode=" + createMode + " toTop=" + toTop);
9398                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9399                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9400                        "moveTaskToDockedStack", animate);
9401            } finally {
9402                Binder.restoreCallingIdentity(ident);
9403            }
9404        }
9405    }
9406
9407    /**
9408     * Moves the top activity in the input stackId to the pinned stack.
9409     *
9410     * @param stackId Id of stack to move the top activity to pinned stack.
9411     * @param bounds Bounds to use for pinned stack.
9412     *
9413     * @return True if the top activity of the input stack was successfully moved to the pinned
9414     *          stack.
9415     */
9416    @Override
9417    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9418        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9419        synchronized (this) {
9420            if (!mSupportsPictureInPicture) {
9421                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9422                        + "Device doesn't support picture-in-pciture mode");
9423            }
9424
9425            long ident = Binder.clearCallingIdentity();
9426            try {
9427                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9428            } finally {
9429                Binder.restoreCallingIdentity(ident);
9430            }
9431        }
9432    }
9433
9434    @Override
9435    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9436            boolean preserveWindows, boolean animate) {
9437        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9438        long ident = Binder.clearCallingIdentity();
9439        try {
9440            synchronized (this) {
9441                if (animate) {
9442                    if (stackId == PINNED_STACK_ID) {
9443                        mWindowManager.animateResizePinnedStack(bounds);
9444                    } else {
9445                        throw new IllegalArgumentException("Stack: " + stackId
9446                                + " doesn't support animated resize.");
9447                    }
9448                } else {
9449                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9450                            null /* tempTaskInsetBounds */, preserveWindows,
9451                            allowResizeInDockedMode);
9452                }
9453            }
9454        } finally {
9455            Binder.restoreCallingIdentity(ident);
9456        }
9457    }
9458
9459    @Override
9460    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9461            Rect tempDockedTaskInsetBounds,
9462            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9463        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9464                "resizeDockedStack()");
9465        long ident = Binder.clearCallingIdentity();
9466        try {
9467            synchronized (this) {
9468                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9469                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9470                        PRESERVE_WINDOWS);
9471            }
9472        } finally {
9473            Binder.restoreCallingIdentity(ident);
9474        }
9475    }
9476
9477    @Override
9478    public void positionTaskInStack(int taskId, int stackId, int position) {
9479        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9480        if (stackId == HOME_STACK_ID) {
9481            throw new IllegalArgumentException(
9482                    "positionTaskInStack: Attempt to change the position of task "
9483                    + taskId + " in/to home stack");
9484        }
9485        synchronized (this) {
9486            long ident = Binder.clearCallingIdentity();
9487            try {
9488                if (DEBUG_STACK) Slog.d(TAG_STACK,
9489                        "positionTaskInStack: positioning task=" + taskId
9490                        + " in stackId=" + stackId + " at position=" + position);
9491                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9492            } finally {
9493                Binder.restoreCallingIdentity(ident);
9494            }
9495        }
9496    }
9497
9498    @Override
9499    public List<StackInfo> getAllStackInfos() {
9500        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9501        long ident = Binder.clearCallingIdentity();
9502        try {
9503            synchronized (this) {
9504                return mStackSupervisor.getAllStackInfosLocked();
9505            }
9506        } finally {
9507            Binder.restoreCallingIdentity(ident);
9508        }
9509    }
9510
9511    @Override
9512    public StackInfo getStackInfo(int stackId) {
9513        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9514        long ident = Binder.clearCallingIdentity();
9515        try {
9516            synchronized (this) {
9517                return mStackSupervisor.getStackInfoLocked(stackId);
9518            }
9519        } finally {
9520            Binder.restoreCallingIdentity(ident);
9521        }
9522    }
9523
9524    @Override
9525    public boolean isInHomeStack(int taskId) {
9526        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9527        long ident = Binder.clearCallingIdentity();
9528        try {
9529            synchronized (this) {
9530                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9531                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9532                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9533            }
9534        } finally {
9535            Binder.restoreCallingIdentity(ident);
9536        }
9537    }
9538
9539    @Override
9540    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9541        synchronized(this) {
9542            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9543        }
9544    }
9545
9546    @Override
9547    public void updateDeviceOwner(String packageName) {
9548        final int callingUid = Binder.getCallingUid();
9549        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9550            throw new SecurityException("updateDeviceOwner called from non-system process");
9551        }
9552        synchronized (this) {
9553            mDeviceOwnerName = packageName;
9554        }
9555    }
9556
9557    @Override
9558    public void updateLockTaskPackages(int userId, String[] packages) {
9559        final int callingUid = Binder.getCallingUid();
9560        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9561            throw new SecurityException("updateLockTaskPackage called from non-system process");
9562        }
9563        synchronized (this) {
9564            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9565                    Arrays.toString(packages));
9566            mLockTaskPackages.put(userId, packages);
9567            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9568        }
9569    }
9570
9571
9572    void startLockTaskModeLocked(TaskRecord task) {
9573        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9574        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9575            return;
9576        }
9577
9578        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9579        // is initiated by system after the pinning request was shown and locked mode is initiated
9580        // by an authorized app directly
9581        final int callingUid = Binder.getCallingUid();
9582        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9583        long ident = Binder.clearCallingIdentity();
9584        try {
9585            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9586            if (!isSystemInitiated) {
9587                task.mLockTaskUid = callingUid;
9588                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9589                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9590                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9591                    StatusBarManagerInternal statusBarManager =
9592                            LocalServices.getService(StatusBarManagerInternal.class);
9593                    if (statusBarManager != null) {
9594                        statusBarManager.showScreenPinningRequest();
9595                    }
9596                    return;
9597                }
9598
9599                if (stack == null || task != stack.topTask()) {
9600                    throw new IllegalArgumentException("Invalid task, not in foreground");
9601                }
9602            }
9603            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9604                    "Locking fully");
9605            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9606                    ActivityManager.LOCK_TASK_MODE_PINNED :
9607                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9608                    "startLockTask", true);
9609        } finally {
9610            Binder.restoreCallingIdentity(ident);
9611        }
9612    }
9613
9614    @Override
9615    public void startLockTaskMode(int taskId) {
9616        synchronized (this) {
9617            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9618            if (task != null) {
9619                startLockTaskModeLocked(task);
9620            }
9621        }
9622    }
9623
9624    @Override
9625    public void startLockTaskMode(IBinder token) {
9626        synchronized (this) {
9627            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9628            if (r == null) {
9629                return;
9630            }
9631            final TaskRecord task = r.task;
9632            if (task != null) {
9633                startLockTaskModeLocked(task);
9634            }
9635        }
9636    }
9637
9638    @Override
9639    public void startLockTaskModeOnCurrent() throws RemoteException {
9640        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9641        long ident = Binder.clearCallingIdentity();
9642        try {
9643            synchronized (this) {
9644                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9645                if (r != null) {
9646                    startLockTaskModeLocked(r.task);
9647                }
9648            }
9649        } finally {
9650            Binder.restoreCallingIdentity(ident);
9651        }
9652    }
9653
9654    @Override
9655    public void stopLockTaskMode() {
9656        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9657        if (lockTask == null) {
9658            // Our work here is done.
9659            return;
9660        }
9661
9662        final int callingUid = Binder.getCallingUid();
9663        final int lockTaskUid = lockTask.mLockTaskUid;
9664        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9665        // It is possible lockTaskMode was started by the system process because
9666        // android:lockTaskMode is set to a locking value in the application manifest instead of
9667        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9668        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9669        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9670                callingUid != lockTaskUid
9671                && (lockTaskUid != 0
9672                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9673            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9674                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9675        }
9676
9677        long ident = Binder.clearCallingIdentity();
9678        try {
9679            Log.d(TAG, "stopLockTaskMode");
9680            // Stop lock task
9681            synchronized (this) {
9682                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9683                        "stopLockTask", true);
9684            }
9685        } finally {
9686            Binder.restoreCallingIdentity(ident);
9687        }
9688    }
9689
9690    @Override
9691    public void stopLockTaskModeOnCurrent() throws RemoteException {
9692        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9693        long ident = Binder.clearCallingIdentity();
9694        try {
9695            stopLockTaskMode();
9696        } finally {
9697            Binder.restoreCallingIdentity(ident);
9698        }
9699    }
9700
9701    @Override
9702    public boolean isInLockTaskMode() {
9703        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9704    }
9705
9706    @Override
9707    public int getLockTaskModeState() {
9708        synchronized (this) {
9709            return mStackSupervisor.getLockTaskModeState();
9710        }
9711    }
9712
9713    @Override
9714    public void showLockTaskEscapeMessage(IBinder token) {
9715        synchronized (this) {
9716            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9717            if (r == null) {
9718                return;
9719            }
9720            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9721        }
9722    }
9723
9724    // =========================================================
9725    // CONTENT PROVIDERS
9726    // =========================================================
9727
9728    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9729        List<ProviderInfo> providers = null;
9730        try {
9731            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9732                    .queryContentProviders(app.processName, app.uid,
9733                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9734                                    | MATCH_DEBUG_TRIAGED_MISSING);
9735            providers = slice != null ? slice.getList() : null;
9736        } catch (RemoteException ex) {
9737        }
9738        if (DEBUG_MU) Slog.v(TAG_MU,
9739                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9740        int userId = app.userId;
9741        if (providers != null) {
9742            int N = providers.size();
9743            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9744            for (int i=0; i<N; i++) {
9745                ProviderInfo cpi =
9746                    (ProviderInfo)providers.get(i);
9747                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9748                        cpi.name, cpi.flags);
9749                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9750                    // This is a singleton provider, but a user besides the
9751                    // default user is asking to initialize a process it runs
9752                    // in...  well, no, it doesn't actually run in this process,
9753                    // it runs in the process of the default user.  Get rid of it.
9754                    providers.remove(i);
9755                    N--;
9756                    i--;
9757                    continue;
9758                }
9759
9760                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9761                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9762                if (cpr == null) {
9763                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9764                    mProviderMap.putProviderByClass(comp, cpr);
9765                }
9766                if (DEBUG_MU) Slog.v(TAG_MU,
9767                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9768                app.pubProviders.put(cpi.name, cpr);
9769                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9770                    // Don't add this if it is a platform component that is marked
9771                    // to run in multiple processes, because this is actually
9772                    // part of the framework so doesn't make sense to track as a
9773                    // separate apk in the process.
9774                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9775                            mProcessStats);
9776                }
9777                notifyPackageUse(cpi.applicationInfo.packageName);
9778            }
9779        }
9780        return providers;
9781    }
9782
9783    /**
9784     * Check if {@link ProcessRecord} has a possible chance at accessing the
9785     * given {@link ProviderInfo}. Final permission checking is always done
9786     * in {@link ContentProvider}.
9787     */
9788    private final String checkContentProviderPermissionLocked(
9789            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9790        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9791        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9792        boolean checkedGrants = false;
9793        if (checkUser) {
9794            // Looking for cross-user grants before enforcing the typical cross-users permissions
9795            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9796            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9797                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9798                    return null;
9799                }
9800                checkedGrants = true;
9801            }
9802            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9803                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9804            if (userId != tmpTargetUserId) {
9805                // When we actually went to determine the final targer user ID, this ended
9806                // up different than our initial check for the authority.  This is because
9807                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9808                // SELF.  So we need to re-check the grants again.
9809                checkedGrants = false;
9810            }
9811        }
9812        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9813                cpi.applicationInfo.uid, cpi.exported)
9814                == PackageManager.PERMISSION_GRANTED) {
9815            return null;
9816        }
9817        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9818                cpi.applicationInfo.uid, cpi.exported)
9819                == PackageManager.PERMISSION_GRANTED) {
9820            return null;
9821        }
9822
9823        PathPermission[] pps = cpi.pathPermissions;
9824        if (pps != null) {
9825            int i = pps.length;
9826            while (i > 0) {
9827                i--;
9828                PathPermission pp = pps[i];
9829                String pprperm = pp.getReadPermission();
9830                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9831                        cpi.applicationInfo.uid, cpi.exported)
9832                        == PackageManager.PERMISSION_GRANTED) {
9833                    return null;
9834                }
9835                String ppwperm = pp.getWritePermission();
9836                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9837                        cpi.applicationInfo.uid, cpi.exported)
9838                        == PackageManager.PERMISSION_GRANTED) {
9839                    return null;
9840                }
9841            }
9842        }
9843        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9844            return null;
9845        }
9846
9847        String msg;
9848        if (!cpi.exported) {
9849            msg = "Permission Denial: opening provider " + cpi.name
9850                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9851                    + ", uid=" + callingUid + ") that is not exported from uid "
9852                    + cpi.applicationInfo.uid;
9853        } else {
9854            msg = "Permission Denial: opening provider " + cpi.name
9855                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9856                    + ", uid=" + callingUid + ") requires "
9857                    + cpi.readPermission + " or " + cpi.writePermission;
9858        }
9859        Slog.w(TAG, msg);
9860        return msg;
9861    }
9862
9863    /**
9864     * Returns if the ContentProvider has granted a uri to callingUid
9865     */
9866    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9867        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9868        if (perms != null) {
9869            for (int i=perms.size()-1; i>=0; i--) {
9870                GrantUri grantUri = perms.keyAt(i);
9871                if (grantUri.sourceUserId == userId || !checkUser) {
9872                    if (matchesProvider(grantUri.uri, cpi)) {
9873                        return true;
9874                    }
9875                }
9876            }
9877        }
9878        return false;
9879    }
9880
9881    /**
9882     * Returns true if the uri authority is one of the authorities specified in the provider.
9883     */
9884    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9885        String uriAuth = uri.getAuthority();
9886        String cpiAuth = cpi.authority;
9887        if (cpiAuth.indexOf(';') == -1) {
9888            return cpiAuth.equals(uriAuth);
9889        }
9890        String[] cpiAuths = cpiAuth.split(";");
9891        int length = cpiAuths.length;
9892        for (int i = 0; i < length; i++) {
9893            if (cpiAuths[i].equals(uriAuth)) return true;
9894        }
9895        return false;
9896    }
9897
9898    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9899            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9900        if (r != null) {
9901            for (int i=0; i<r.conProviders.size(); i++) {
9902                ContentProviderConnection conn = r.conProviders.get(i);
9903                if (conn.provider == cpr) {
9904                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9905                            "Adding provider requested by "
9906                            + r.processName + " from process "
9907                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9908                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9909                    if (stable) {
9910                        conn.stableCount++;
9911                        conn.numStableIncs++;
9912                    } else {
9913                        conn.unstableCount++;
9914                        conn.numUnstableIncs++;
9915                    }
9916                    return conn;
9917                }
9918            }
9919            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9920            if (stable) {
9921                conn.stableCount = 1;
9922                conn.numStableIncs = 1;
9923            } else {
9924                conn.unstableCount = 1;
9925                conn.numUnstableIncs = 1;
9926            }
9927            cpr.connections.add(conn);
9928            r.conProviders.add(conn);
9929            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9930            return conn;
9931        }
9932        cpr.addExternalProcessHandleLocked(externalProcessToken);
9933        return null;
9934    }
9935
9936    boolean decProviderCountLocked(ContentProviderConnection conn,
9937            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9938        if (conn != null) {
9939            cpr = conn.provider;
9940            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9941                    "Removing provider requested by "
9942                    + conn.client.processName + " from process "
9943                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9944                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9945            if (stable) {
9946                conn.stableCount--;
9947            } else {
9948                conn.unstableCount--;
9949            }
9950            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9951                cpr.connections.remove(conn);
9952                conn.client.conProviders.remove(conn);
9953                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9954                    // The client is more important than last activity -- note the time this
9955                    // is happening, so we keep the old provider process around a bit as last
9956                    // activity to avoid thrashing it.
9957                    if (cpr.proc != null) {
9958                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9959                    }
9960                }
9961                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9962                return true;
9963            }
9964            return false;
9965        }
9966        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9967        return false;
9968    }
9969
9970    private void checkTime(long startTime, String where) {
9971        long now = SystemClock.elapsedRealtime();
9972        if ((now-startTime) > 1000) {
9973            // If we are taking more than a second, log about it.
9974            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9975        }
9976    }
9977
9978    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9979            String name, IBinder token, boolean stable, int userId) {
9980        ContentProviderRecord cpr;
9981        ContentProviderConnection conn = null;
9982        ProviderInfo cpi = null;
9983
9984        synchronized(this) {
9985            long startTime = SystemClock.elapsedRealtime();
9986
9987            ProcessRecord r = null;
9988            if (caller != null) {
9989                r = getRecordForAppLocked(caller);
9990                if (r == null) {
9991                    throw new SecurityException(
9992                            "Unable to find app for caller " + caller
9993                          + " (pid=" + Binder.getCallingPid()
9994                          + ") when getting content provider " + name);
9995                }
9996            }
9997
9998            boolean checkCrossUser = true;
9999
10000            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10001
10002            // First check if this content provider has been published...
10003            cpr = mProviderMap.getProviderByName(name, userId);
10004            // If that didn't work, check if it exists for user 0 and then
10005            // verify that it's a singleton provider before using it.
10006            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10007                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10008                if (cpr != null) {
10009                    cpi = cpr.info;
10010                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10011                            cpi.name, cpi.flags)
10012                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10013                        userId = UserHandle.USER_SYSTEM;
10014                        checkCrossUser = false;
10015                    } else {
10016                        cpr = null;
10017                        cpi = null;
10018                    }
10019                }
10020            }
10021
10022            boolean providerRunning = cpr != null;
10023            if (providerRunning) {
10024                cpi = cpr.info;
10025                String msg;
10026                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10027                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10028                        != null) {
10029                    throw new SecurityException(msg);
10030                }
10031                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10032
10033                if (r != null && cpr.canRunHere(r)) {
10034                    // This provider has been published or is in the process
10035                    // of being published...  but it is also allowed to run
10036                    // in the caller's process, so don't make a connection
10037                    // and just let the caller instantiate its own instance.
10038                    ContentProviderHolder holder = cpr.newHolder(null);
10039                    // don't give caller the provider object, it needs
10040                    // to make its own.
10041                    holder.provider = null;
10042                    return holder;
10043                }
10044
10045                final long origId = Binder.clearCallingIdentity();
10046
10047                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10048
10049                // In this case the provider instance already exists, so we can
10050                // return it right away.
10051                conn = incProviderCountLocked(r, cpr, token, stable);
10052                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10053                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10054                        // If this is a perceptible app accessing the provider,
10055                        // make sure to count it as being accessed and thus
10056                        // back up on the LRU list.  This is good because
10057                        // content providers are often expensive to start.
10058                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10059                        updateLruProcessLocked(cpr.proc, false, null);
10060                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10061                    }
10062                }
10063
10064                if (cpr.proc != null) {
10065                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10066                    boolean success = updateOomAdjLocked(cpr.proc);
10067                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10068                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10069                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10070                    // NOTE: there is still a race here where a signal could be
10071                    // pending on the process even though we managed to update its
10072                    // adj level.  Not sure what to do about this, but at least
10073                    // the race is now smaller.
10074                    if (!success) {
10075                        // Uh oh...  it looks like the provider's process
10076                        // has been killed on us.  We need to wait for a new
10077                        // process to be started, and make sure its death
10078                        // doesn't kill our process.
10079                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10080                                + " is crashing; detaching " + r);
10081                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10082                        checkTime(startTime, "getContentProviderImpl: before appDied");
10083                        appDiedLocked(cpr.proc);
10084                        checkTime(startTime, "getContentProviderImpl: after appDied");
10085                        if (!lastRef) {
10086                            // This wasn't the last ref our process had on
10087                            // the provider...  we have now been killed, bail.
10088                            return null;
10089                        }
10090                        providerRunning = false;
10091                        conn = null;
10092                    }
10093                }
10094
10095                Binder.restoreCallingIdentity(origId);
10096            }
10097
10098            if (!providerRunning) {
10099                try {
10100                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10101                    cpi = AppGlobals.getPackageManager().
10102                        resolveContentProvider(name,
10103                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10104                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10105                } catch (RemoteException ex) {
10106                }
10107                if (cpi == null) {
10108                    return null;
10109                }
10110                // If the provider is a singleton AND
10111                // (it's a call within the same user || the provider is a
10112                // privileged app)
10113                // Then allow connecting to the singleton provider
10114                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10115                        cpi.name, cpi.flags)
10116                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10117                if (singleton) {
10118                    userId = UserHandle.USER_SYSTEM;
10119                }
10120                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10121                checkTime(startTime, "getContentProviderImpl: got app info for user");
10122
10123                String msg;
10124                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10125                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10126                        != null) {
10127                    throw new SecurityException(msg);
10128                }
10129                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10130
10131                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10132                        && !cpi.processName.equals("system")) {
10133                    // If this content provider does not run in the system
10134                    // process, and the system is not yet ready to run other
10135                    // processes, then fail fast instead of hanging.
10136                    throw new IllegalArgumentException(
10137                            "Attempt to launch content provider before system ready");
10138                }
10139
10140                // Make sure that the user who owns this provider is running.  If not,
10141                // we don't want to allow it to run.
10142                if (!mUserController.isUserRunningLocked(userId, 0)) {
10143                    Slog.w(TAG, "Unable to launch app "
10144                            + cpi.applicationInfo.packageName + "/"
10145                            + cpi.applicationInfo.uid + " for provider "
10146                            + name + ": user " + userId + " is stopped");
10147                    return null;
10148                }
10149
10150                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10151                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10152                cpr = mProviderMap.getProviderByClass(comp, userId);
10153                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10154                final boolean firstClass = cpr == null;
10155                if (firstClass) {
10156                    final long ident = Binder.clearCallingIdentity();
10157
10158                    // If permissions need a review before any of the app components can run,
10159                    // we return no provider and launch a review activity if the calling app
10160                    // is in the foreground.
10161                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10162                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10163                            return null;
10164                        }
10165                    }
10166
10167                    try {
10168                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10169                        ApplicationInfo ai =
10170                            AppGlobals.getPackageManager().
10171                                getApplicationInfo(
10172                                        cpi.applicationInfo.packageName,
10173                                        STOCK_PM_FLAGS, userId);
10174                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10175                        if (ai == null) {
10176                            Slog.w(TAG, "No package info for content provider "
10177                                    + cpi.name);
10178                            return null;
10179                        }
10180                        ai = getAppInfoForUser(ai, userId);
10181                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10182                    } catch (RemoteException ex) {
10183                        // pm is in same process, this will never happen.
10184                    } finally {
10185                        Binder.restoreCallingIdentity(ident);
10186                    }
10187                }
10188
10189                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10190
10191                if (r != null && cpr.canRunHere(r)) {
10192                    // If this is a multiprocess provider, then just return its
10193                    // info and allow the caller to instantiate it.  Only do
10194                    // this if the provider is the same user as the caller's
10195                    // process, or can run as root (so can be in any process).
10196                    return cpr.newHolder(null);
10197                }
10198
10199                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10200                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10201                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10202
10203                // This is single process, and our app is now connecting to it.
10204                // See if we are already in the process of launching this
10205                // provider.
10206                final int N = mLaunchingProviders.size();
10207                int i;
10208                for (i = 0; i < N; i++) {
10209                    if (mLaunchingProviders.get(i) == cpr) {
10210                        break;
10211                    }
10212                }
10213
10214                // If the provider is not already being launched, then get it
10215                // started.
10216                if (i >= N) {
10217                    final long origId = Binder.clearCallingIdentity();
10218
10219                    try {
10220                        // Content provider is now in use, its package can't be stopped.
10221                        try {
10222                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10223                            AppGlobals.getPackageManager().setPackageStoppedState(
10224                                    cpr.appInfo.packageName, false, userId);
10225                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10226                        } catch (RemoteException e) {
10227                        } catch (IllegalArgumentException e) {
10228                            Slog.w(TAG, "Failed trying to unstop package "
10229                                    + cpr.appInfo.packageName + ": " + e);
10230                        }
10231
10232                        // Use existing process if already started
10233                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10234                        ProcessRecord proc = getProcessRecordLocked(
10235                                cpi.processName, cpr.appInfo.uid, false);
10236                        if (proc != null && proc.thread != null) {
10237                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10238                                    "Installing in existing process " + proc);
10239                            if (!proc.pubProviders.containsKey(cpi.name)) {
10240                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10241                                proc.pubProviders.put(cpi.name, cpr);
10242                                try {
10243                                    proc.thread.scheduleInstallProvider(cpi);
10244                                } catch (RemoteException e) {
10245                                }
10246                            }
10247                        } else {
10248                            checkTime(startTime, "getContentProviderImpl: before start process");
10249                            proc = startProcessLocked(cpi.processName,
10250                                    cpr.appInfo, false, 0, "content provider",
10251                                    new ComponentName(cpi.applicationInfo.packageName,
10252                                            cpi.name), false, false, false);
10253                            checkTime(startTime, "getContentProviderImpl: after start process");
10254                            if (proc == null) {
10255                                Slog.w(TAG, "Unable to launch app "
10256                                        + cpi.applicationInfo.packageName + "/"
10257                                        + cpi.applicationInfo.uid + " for provider "
10258                                        + name + ": process is bad");
10259                                return null;
10260                            }
10261                        }
10262                        cpr.launchingApp = proc;
10263                        mLaunchingProviders.add(cpr);
10264                    } finally {
10265                        Binder.restoreCallingIdentity(origId);
10266                    }
10267                }
10268
10269                checkTime(startTime, "getContentProviderImpl: updating data structures");
10270
10271                // Make sure the provider is published (the same provider class
10272                // may be published under multiple names).
10273                if (firstClass) {
10274                    mProviderMap.putProviderByClass(comp, cpr);
10275                }
10276
10277                mProviderMap.putProviderByName(name, cpr);
10278                conn = incProviderCountLocked(r, cpr, token, stable);
10279                if (conn != null) {
10280                    conn.waiting = true;
10281                }
10282            }
10283            checkTime(startTime, "getContentProviderImpl: done!");
10284        }
10285
10286        // Wait for the provider to be published...
10287        synchronized (cpr) {
10288            while (cpr.provider == null) {
10289                if (cpr.launchingApp == null) {
10290                    Slog.w(TAG, "Unable to launch app "
10291                            + cpi.applicationInfo.packageName + "/"
10292                            + cpi.applicationInfo.uid + " for provider "
10293                            + name + ": launching app became null");
10294                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10295                            UserHandle.getUserId(cpi.applicationInfo.uid),
10296                            cpi.applicationInfo.packageName,
10297                            cpi.applicationInfo.uid, name);
10298                    return null;
10299                }
10300                try {
10301                    if (DEBUG_MU) Slog.v(TAG_MU,
10302                            "Waiting to start provider " + cpr
10303                            + " launchingApp=" + cpr.launchingApp);
10304                    if (conn != null) {
10305                        conn.waiting = true;
10306                    }
10307                    cpr.wait();
10308                } catch (InterruptedException ex) {
10309                } finally {
10310                    if (conn != null) {
10311                        conn.waiting = false;
10312                    }
10313                }
10314            }
10315        }
10316        return cpr != null ? cpr.newHolder(conn) : null;
10317    }
10318
10319    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10320            ProcessRecord r, final int userId) {
10321        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10322                cpi.packageName, r.userId)) {
10323
10324            final boolean callerForeground = r != null ? r.setSchedGroup
10325                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10326
10327            // Show a permission review UI only for starting from a foreground app
10328            if (!callerForeground) {
10329                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10330                        + cpi.packageName + " requires a permissions review");
10331                return false;
10332            }
10333
10334            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10335            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10336                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10337            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10338
10339            if (DEBUG_PERMISSIONS_REVIEW) {
10340                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10341                        + "for package " + cpi.packageName);
10342            }
10343
10344            final UserHandle userHandle = new UserHandle(userId);
10345            mHandler.post(new Runnable() {
10346                @Override
10347                public void run() {
10348                    mContext.startActivityAsUser(intent, userHandle);
10349                }
10350            });
10351
10352            return false;
10353        }
10354
10355        return true;
10356    }
10357
10358    PackageManagerInternal getPackageManagerInternalLocked() {
10359        if (mPackageManagerInt == null) {
10360            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10361        }
10362        return mPackageManagerInt;
10363    }
10364
10365    @Override
10366    public final ContentProviderHolder getContentProvider(
10367            IApplicationThread caller, String name, int userId, boolean stable) {
10368        enforceNotIsolatedCaller("getContentProvider");
10369        if (caller == null) {
10370            String msg = "null IApplicationThread when getting content provider "
10371                    + name;
10372            Slog.w(TAG, msg);
10373            throw new SecurityException(msg);
10374        }
10375        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10376        // with cross-user grant.
10377        return getContentProviderImpl(caller, name, null, stable, userId);
10378    }
10379
10380    public ContentProviderHolder getContentProviderExternal(
10381            String name, int userId, IBinder token) {
10382        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10383            "Do not have permission in call getContentProviderExternal()");
10384        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10385                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10386        return getContentProviderExternalUnchecked(name, token, userId);
10387    }
10388
10389    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10390            IBinder token, int userId) {
10391        return getContentProviderImpl(null, name, token, true, userId);
10392    }
10393
10394    /**
10395     * Drop a content provider from a ProcessRecord's bookkeeping
10396     */
10397    public void removeContentProvider(IBinder connection, boolean stable) {
10398        enforceNotIsolatedCaller("removeContentProvider");
10399        long ident = Binder.clearCallingIdentity();
10400        try {
10401            synchronized (this) {
10402                ContentProviderConnection conn;
10403                try {
10404                    conn = (ContentProviderConnection)connection;
10405                } catch (ClassCastException e) {
10406                    String msg ="removeContentProvider: " + connection
10407                            + " not a ContentProviderConnection";
10408                    Slog.w(TAG, msg);
10409                    throw new IllegalArgumentException(msg);
10410                }
10411                if (conn == null) {
10412                    throw new NullPointerException("connection is null");
10413                }
10414                if (decProviderCountLocked(conn, null, null, stable)) {
10415                    updateOomAdjLocked();
10416                }
10417            }
10418        } finally {
10419            Binder.restoreCallingIdentity(ident);
10420        }
10421    }
10422
10423    public void removeContentProviderExternal(String name, IBinder token) {
10424        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10425            "Do not have permission in call removeContentProviderExternal()");
10426        int userId = UserHandle.getCallingUserId();
10427        long ident = Binder.clearCallingIdentity();
10428        try {
10429            removeContentProviderExternalUnchecked(name, token, userId);
10430        } finally {
10431            Binder.restoreCallingIdentity(ident);
10432        }
10433    }
10434
10435    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10436        synchronized (this) {
10437            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10438            if(cpr == null) {
10439                //remove from mProvidersByClass
10440                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10441                return;
10442            }
10443
10444            //update content provider record entry info
10445            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10446            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10447            if (localCpr.hasExternalProcessHandles()) {
10448                if (localCpr.removeExternalProcessHandleLocked(token)) {
10449                    updateOomAdjLocked();
10450                } else {
10451                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10452                            + " with no external reference for token: "
10453                            + token + ".");
10454                }
10455            } else {
10456                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10457                        + " with no external references.");
10458            }
10459        }
10460    }
10461
10462    public final void publishContentProviders(IApplicationThread caller,
10463            List<ContentProviderHolder> providers) {
10464        if (providers == null) {
10465            return;
10466        }
10467
10468        enforceNotIsolatedCaller("publishContentProviders");
10469        synchronized (this) {
10470            final ProcessRecord r = getRecordForAppLocked(caller);
10471            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10472            if (r == null) {
10473                throw new SecurityException(
10474                        "Unable to find app for caller " + caller
10475                      + " (pid=" + Binder.getCallingPid()
10476                      + ") when publishing content providers");
10477            }
10478
10479            final long origId = Binder.clearCallingIdentity();
10480
10481            final int N = providers.size();
10482            for (int i = 0; i < N; i++) {
10483                ContentProviderHolder src = providers.get(i);
10484                if (src == null || src.info == null || src.provider == null) {
10485                    continue;
10486                }
10487                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10488                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10489                if (dst != null) {
10490                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10491                    mProviderMap.putProviderByClass(comp, dst);
10492                    String names[] = dst.info.authority.split(";");
10493                    for (int j = 0; j < names.length; j++) {
10494                        mProviderMap.putProviderByName(names[j], dst);
10495                    }
10496
10497                    int launchingCount = mLaunchingProviders.size();
10498                    int j;
10499                    boolean wasInLaunchingProviders = false;
10500                    for (j = 0; j < launchingCount; j++) {
10501                        if (mLaunchingProviders.get(j) == dst) {
10502                            mLaunchingProviders.remove(j);
10503                            wasInLaunchingProviders = true;
10504                            j--;
10505                            launchingCount--;
10506                        }
10507                    }
10508                    if (wasInLaunchingProviders) {
10509                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10510                    }
10511                    synchronized (dst) {
10512                        dst.provider = src.provider;
10513                        dst.proc = r;
10514                        dst.notifyAll();
10515                    }
10516                    updateOomAdjLocked(r);
10517                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10518                            src.info.authority);
10519                }
10520            }
10521
10522            Binder.restoreCallingIdentity(origId);
10523        }
10524    }
10525
10526    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10527        ContentProviderConnection conn;
10528        try {
10529            conn = (ContentProviderConnection)connection;
10530        } catch (ClassCastException e) {
10531            String msg ="refContentProvider: " + connection
10532                    + " not a ContentProviderConnection";
10533            Slog.w(TAG, msg);
10534            throw new IllegalArgumentException(msg);
10535        }
10536        if (conn == null) {
10537            throw new NullPointerException("connection is null");
10538        }
10539
10540        synchronized (this) {
10541            if (stable > 0) {
10542                conn.numStableIncs += stable;
10543            }
10544            stable = conn.stableCount + stable;
10545            if (stable < 0) {
10546                throw new IllegalStateException("stableCount < 0: " + stable);
10547            }
10548
10549            if (unstable > 0) {
10550                conn.numUnstableIncs += unstable;
10551            }
10552            unstable = conn.unstableCount + unstable;
10553            if (unstable < 0) {
10554                throw new IllegalStateException("unstableCount < 0: " + unstable);
10555            }
10556
10557            if ((stable+unstable) <= 0) {
10558                throw new IllegalStateException("ref counts can't go to zero here: stable="
10559                        + stable + " unstable=" + unstable);
10560            }
10561            conn.stableCount = stable;
10562            conn.unstableCount = unstable;
10563            return !conn.dead;
10564        }
10565    }
10566
10567    public void unstableProviderDied(IBinder connection) {
10568        ContentProviderConnection conn;
10569        try {
10570            conn = (ContentProviderConnection)connection;
10571        } catch (ClassCastException e) {
10572            String msg ="refContentProvider: " + connection
10573                    + " not a ContentProviderConnection";
10574            Slog.w(TAG, msg);
10575            throw new IllegalArgumentException(msg);
10576        }
10577        if (conn == null) {
10578            throw new NullPointerException("connection is null");
10579        }
10580
10581        // Safely retrieve the content provider associated with the connection.
10582        IContentProvider provider;
10583        synchronized (this) {
10584            provider = conn.provider.provider;
10585        }
10586
10587        if (provider == null) {
10588            // Um, yeah, we're way ahead of you.
10589            return;
10590        }
10591
10592        // Make sure the caller is being honest with us.
10593        if (provider.asBinder().pingBinder()) {
10594            // Er, no, still looks good to us.
10595            synchronized (this) {
10596                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10597                        + " says " + conn + " died, but we don't agree");
10598                return;
10599            }
10600        }
10601
10602        // Well look at that!  It's dead!
10603        synchronized (this) {
10604            if (conn.provider.provider != provider) {
10605                // But something changed...  good enough.
10606                return;
10607            }
10608
10609            ProcessRecord proc = conn.provider.proc;
10610            if (proc == null || proc.thread == null) {
10611                // Seems like the process is already cleaned up.
10612                return;
10613            }
10614
10615            // As far as we're concerned, this is just like receiving a
10616            // death notification...  just a bit prematurely.
10617            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10618                    + ") early provider death");
10619            final long ident = Binder.clearCallingIdentity();
10620            try {
10621                appDiedLocked(proc);
10622            } finally {
10623                Binder.restoreCallingIdentity(ident);
10624            }
10625        }
10626    }
10627
10628    @Override
10629    public void appNotRespondingViaProvider(IBinder connection) {
10630        enforceCallingPermission(
10631                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10632
10633        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10634        if (conn == null) {
10635            Slog.w(TAG, "ContentProviderConnection is null");
10636            return;
10637        }
10638
10639        final ProcessRecord host = conn.provider.proc;
10640        if (host == null) {
10641            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10642            return;
10643        }
10644
10645        final long token = Binder.clearCallingIdentity();
10646        try {
10647            mAppErrors.appNotResponding(host, null, null, false, "ContentProvider not responding");
10648        } finally {
10649            Binder.restoreCallingIdentity(token);
10650        }
10651    }
10652
10653    public final void installSystemProviders() {
10654        List<ProviderInfo> providers;
10655        synchronized (this) {
10656            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10657            providers = generateApplicationProvidersLocked(app);
10658            if (providers != null) {
10659                for (int i=providers.size()-1; i>=0; i--) {
10660                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10661                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10662                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10663                                + ": not system .apk");
10664                        providers.remove(i);
10665                    }
10666                }
10667            }
10668        }
10669        if (providers != null) {
10670            mSystemThread.installSystemProviders(providers);
10671        }
10672
10673        mCoreSettingsObserver = new CoreSettingsObserver(this);
10674        mFontScaleSettingObserver = new FontScaleSettingObserver();
10675
10676        //mUsageStatsService.monitorPackages();
10677    }
10678
10679    /**
10680     * When a user is unlocked, we need to install encryption-unaware providers
10681     * belonging to any running apps.
10682     */
10683    private void installEncryptionUnawareProviders(int userId) {
10684        if (!StorageManager.isFileBasedEncryptionEnabled()) {
10685            // TODO: eventually pivot this back to look at current user state,
10686            // similar to the comment in UserManager.isUserUnlocked(), but for
10687            // now, if we started apps when "unlocked" then unaware providers
10688            // have already been spun up.
10689            return;
10690        }
10691
10692        synchronized (this) {
10693            final int NP = mProcessNames.getMap().size();
10694            for (int ip = 0; ip < NP; ip++) {
10695                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10696                final int NA = apps.size();
10697                for (int ia = 0; ia < NA; ia++) {
10698                    final ProcessRecord app = apps.valueAt(ia);
10699                    if (app.userId != userId || app.thread == null) continue;
10700
10701                    final int NG = app.pkgList.size();
10702                    for (int ig = 0; ig < NG; ig++) {
10703                        try {
10704                            final String pkgName = app.pkgList.keyAt(ig);
10705                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10706                                    .getPackageInfo(pkgName,
10707                                            GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE, userId);
10708                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10709                                for (ProviderInfo provInfo : pkgInfo.providers) {
10710                                    Log.v(TAG, "Installing " + provInfo);
10711                                    app.thread.scheduleInstallProvider(provInfo);
10712                                }
10713                            }
10714                        } catch (RemoteException ignored) {
10715                        }
10716                    }
10717                }
10718            }
10719        }
10720    }
10721
10722    /**
10723     * Allows apps to retrieve the MIME type of a URI.
10724     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10725     * users, then it does not need permission to access the ContentProvider.
10726     * Either, it needs cross-user uri grants.
10727     *
10728     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10729     *
10730     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10731     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10732     */
10733    public String getProviderMimeType(Uri uri, int userId) {
10734        enforceNotIsolatedCaller("getProviderMimeType");
10735        final String name = uri.getAuthority();
10736        int callingUid = Binder.getCallingUid();
10737        int callingPid = Binder.getCallingPid();
10738        long ident = 0;
10739        boolean clearedIdentity = false;
10740        synchronized (this) {
10741            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10742        }
10743        if (canClearIdentity(callingPid, callingUid, userId)) {
10744            clearedIdentity = true;
10745            ident = Binder.clearCallingIdentity();
10746        }
10747        ContentProviderHolder holder = null;
10748        try {
10749            holder = getContentProviderExternalUnchecked(name, null, userId);
10750            if (holder != null) {
10751                return holder.provider.getType(uri);
10752            }
10753        } catch (RemoteException e) {
10754            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10755            return null;
10756        } finally {
10757            // We need to clear the identity to call removeContentProviderExternalUnchecked
10758            if (!clearedIdentity) {
10759                ident = Binder.clearCallingIdentity();
10760            }
10761            try {
10762                if (holder != null) {
10763                    removeContentProviderExternalUnchecked(name, null, userId);
10764                }
10765            } finally {
10766                Binder.restoreCallingIdentity(ident);
10767            }
10768        }
10769
10770        return null;
10771    }
10772
10773    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10774        if (UserHandle.getUserId(callingUid) == userId) {
10775            return true;
10776        }
10777        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10778                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10779                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10780                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10781                return true;
10782        }
10783        return false;
10784    }
10785
10786    // =========================================================
10787    // GLOBAL MANAGEMENT
10788    // =========================================================
10789
10790    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10791            boolean isolated, int isolatedUid) {
10792        String proc = customProcess != null ? customProcess : info.processName;
10793        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10794        final int userId = UserHandle.getUserId(info.uid);
10795        int uid = info.uid;
10796        if (isolated) {
10797            if (isolatedUid == 0) {
10798                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10799                while (true) {
10800                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10801                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10802                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10803                    }
10804                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10805                    mNextIsolatedProcessUid++;
10806                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10807                        // No process for this uid, use it.
10808                        break;
10809                    }
10810                    stepsLeft--;
10811                    if (stepsLeft <= 0) {
10812                        return null;
10813                    }
10814                }
10815            } else {
10816                // Special case for startIsolatedProcess (internal only), where
10817                // the uid of the isolated process is specified by the caller.
10818                uid = isolatedUid;
10819            }
10820        }
10821        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10822        if (!mBooted && !mBooting
10823                && userId == UserHandle.USER_SYSTEM
10824                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10825            r.persistent = true;
10826        }
10827        addProcessNameLocked(r);
10828        return r;
10829    }
10830
10831    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10832            String abiOverride) {
10833        ProcessRecord app;
10834        if (!isolated) {
10835            app = getProcessRecordLocked(info.processName, info.uid, true);
10836        } else {
10837            app = null;
10838        }
10839
10840        if (app == null) {
10841            app = newProcessRecordLocked(info, null, isolated, 0);
10842            updateLruProcessLocked(app, false, null);
10843            updateOomAdjLocked();
10844        }
10845
10846        // This package really, really can not be stopped.
10847        try {
10848            AppGlobals.getPackageManager().setPackageStoppedState(
10849                    info.packageName, false, UserHandle.getUserId(app.uid));
10850        } catch (RemoteException e) {
10851        } catch (IllegalArgumentException e) {
10852            Slog.w(TAG, "Failed trying to unstop package "
10853                    + info.packageName + ": " + e);
10854        }
10855
10856        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10857            app.persistent = true;
10858            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10859        }
10860        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10861            mPersistentStartingProcesses.add(app);
10862            startProcessLocked(app, "added application", app.processName, abiOverride,
10863                    null /* entryPoint */, null /* entryPointArgs */);
10864        }
10865
10866        return app;
10867    }
10868
10869    public void unhandledBack() {
10870        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10871                "unhandledBack()");
10872
10873        synchronized(this) {
10874            final long origId = Binder.clearCallingIdentity();
10875            try {
10876                getFocusedStack().unhandledBackLocked();
10877            } finally {
10878                Binder.restoreCallingIdentity(origId);
10879            }
10880        }
10881    }
10882
10883    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10884        enforceNotIsolatedCaller("openContentUri");
10885        final int userId = UserHandle.getCallingUserId();
10886        String name = uri.getAuthority();
10887        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10888        ParcelFileDescriptor pfd = null;
10889        if (cph != null) {
10890            // We record the binder invoker's uid in thread-local storage before
10891            // going to the content provider to open the file.  Later, in the code
10892            // that handles all permissions checks, we look for this uid and use
10893            // that rather than the Activity Manager's own uid.  The effect is that
10894            // we do the check against the caller's permissions even though it looks
10895            // to the content provider like the Activity Manager itself is making
10896            // the request.
10897            Binder token = new Binder();
10898            sCallerIdentity.set(new Identity(
10899                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10900            try {
10901                pfd = cph.provider.openFile(null, uri, "r", null, token);
10902            } catch (FileNotFoundException e) {
10903                // do nothing; pfd will be returned null
10904            } finally {
10905                // Ensure that whatever happens, we clean up the identity state
10906                sCallerIdentity.remove();
10907                // Ensure we're done with the provider.
10908                removeContentProviderExternalUnchecked(name, null, userId);
10909            }
10910        } else {
10911            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10912        }
10913        return pfd;
10914    }
10915
10916    // Actually is sleeping or shutting down or whatever else in the future
10917    // is an inactive state.
10918    public boolean isSleepingOrShuttingDown() {
10919        return isSleeping() || mShuttingDown;
10920    }
10921
10922    public boolean isSleeping() {
10923        return mSleeping;
10924    }
10925
10926    void onWakefulnessChanged(int wakefulness) {
10927        synchronized(this) {
10928            mWakefulness = wakefulness;
10929            updateSleepIfNeededLocked();
10930        }
10931    }
10932
10933    void finishRunningVoiceLocked() {
10934        Slog.d(TAG, "finishRunningVoiceLocked()  >>>>");
10935        if (mRunningVoice != null) {
10936            mRunningVoice = null;
10937            mVoiceWakeLock.release();
10938            updateSleepIfNeededLocked();
10939        }
10940    }
10941
10942    void startTimeTrackingFocusedActivityLocked() {
10943        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10944            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10945        }
10946    }
10947
10948    void updateSleepIfNeededLocked() {
10949        if (mSleeping && !shouldSleepLocked()) {
10950            mSleeping = false;
10951            startTimeTrackingFocusedActivityLocked();
10952            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10953            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10954            updateOomAdjLocked();
10955        } else if (!mSleeping && shouldSleepLocked()) {
10956            mSleeping = true;
10957            if (mCurAppTimeTracker != null) {
10958                mCurAppTimeTracker.stop();
10959            }
10960            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10961            mStackSupervisor.goingToSleepLocked();
10962            updateOomAdjLocked();
10963
10964            // Initialize the wake times of all processes.
10965            checkExcessivePowerUsageLocked(false);
10966            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10967            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10968            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10969        }
10970    }
10971
10972    private boolean shouldSleepLocked() {
10973        // Resume applications while running a voice interactor.
10974        if (mRunningVoice != null) {
10975            return false;
10976        }
10977
10978        // TODO: Transform the lock screen state into a sleep token instead.
10979        switch (mWakefulness) {
10980            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10981            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10982            case PowerManagerInternal.WAKEFULNESS_DOZING:
10983                // Pause applications whenever the lock screen is shown or any sleep
10984                // tokens have been acquired.
10985                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10986            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10987            default:
10988                // If we're asleep then pause applications unconditionally.
10989                return true;
10990        }
10991    }
10992
10993    /** Pokes the task persister. */
10994    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10995        mRecentTasks.notifyTaskPersisterLocked(task, flush);
10996    }
10997
10998    /** Notifies all listeners when the task stack has changed. */
10999    void notifyTaskStackChangedLocked() {
11000        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11001        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11002        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11003        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11004    }
11005
11006    /** Notifies all listeners when an Activity is pinned. */
11007    void notifyActivityPinnedLocked() {
11008        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11009        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11010    }
11011
11012    /**
11013     * Notifies all listeners when an attempt was made to start an an activity that is already
11014     * running in the pinned stack and the activity was not actually started, but the task is
11015     * either brought to the front or a new Intent is delivered to it.
11016     */
11017    void notifyPinnedActivityRestartAttemptLocked() {
11018        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11019        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11020    }
11021
11022    @Override
11023    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11024        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11025    }
11026
11027    @Override
11028    public boolean shutdown(int timeout) {
11029        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11030                != PackageManager.PERMISSION_GRANTED) {
11031            throw new SecurityException("Requires permission "
11032                    + android.Manifest.permission.SHUTDOWN);
11033        }
11034
11035        boolean timedout = false;
11036
11037        synchronized(this) {
11038            mShuttingDown = true;
11039            updateEventDispatchingLocked();
11040            timedout = mStackSupervisor.shutdownLocked(timeout);
11041        }
11042
11043        mAppOpsService.shutdown();
11044        if (mUsageStatsService != null) {
11045            mUsageStatsService.prepareShutdown();
11046        }
11047        mBatteryStatsService.shutdown();
11048        synchronized (this) {
11049            mProcessStats.shutdownLocked();
11050            notifyTaskPersisterLocked(null, true);
11051        }
11052
11053        return timedout;
11054    }
11055
11056    public final void activitySlept(IBinder token) {
11057        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11058
11059        final long origId = Binder.clearCallingIdentity();
11060
11061        synchronized (this) {
11062            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11063            if (r != null) {
11064                mStackSupervisor.activitySleptLocked(r);
11065            }
11066        }
11067
11068        Binder.restoreCallingIdentity(origId);
11069    }
11070
11071    private String lockScreenShownToString() {
11072        switch (mLockScreenShown) {
11073            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11074            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11075            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11076            default: return "Unknown=" + mLockScreenShown;
11077        }
11078    }
11079
11080    void logLockScreen(String msg) {
11081        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11082                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11083                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11084                + " mSleeping=" + mSleeping);
11085    }
11086
11087    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11088        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11089        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11090        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11091            boolean wasRunningVoice = mRunningVoice != null;
11092            mRunningVoice = session;
11093            if (!wasRunningVoice) {
11094                mVoiceWakeLock.acquire();
11095                updateSleepIfNeededLocked();
11096            }
11097        }
11098    }
11099
11100    private void updateEventDispatchingLocked() {
11101        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11102    }
11103
11104    public void setLockScreenShown(boolean shown) {
11105        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11106                != PackageManager.PERMISSION_GRANTED) {
11107            throw new SecurityException("Requires permission "
11108                    + android.Manifest.permission.DEVICE_POWER);
11109        }
11110
11111        final int user = UserHandle.myUserId();
11112        synchronized(this) {
11113            long ident = Binder.clearCallingIdentity();
11114            try {
11115                if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
11116                    startHomeActivityLocked(user, "setLockScreenShown");
11117                }
11118                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11119                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11120                updateSleepIfNeededLocked();
11121            } finally {
11122                Binder.restoreCallingIdentity(ident);
11123            }
11124        }
11125    }
11126
11127    @Override
11128    public void stopAppSwitches() {
11129        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11130                != PackageManager.PERMISSION_GRANTED) {
11131            throw new SecurityException("viewquires permission "
11132                    + android.Manifest.permission.STOP_APP_SWITCHES);
11133        }
11134
11135        synchronized(this) {
11136            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11137                    + APP_SWITCH_DELAY_TIME;
11138            mDidAppSwitch = false;
11139            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11140            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11141            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11142        }
11143    }
11144
11145    public void resumeAppSwitches() {
11146        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11147                != PackageManager.PERMISSION_GRANTED) {
11148            throw new SecurityException("Requires permission "
11149                    + android.Manifest.permission.STOP_APP_SWITCHES);
11150        }
11151
11152        synchronized(this) {
11153            // Note that we don't execute any pending app switches... we will
11154            // let those wait until either the timeout, or the next start
11155            // activity request.
11156            mAppSwitchesAllowedTime = 0;
11157        }
11158    }
11159
11160    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11161            int callingPid, int callingUid, String name) {
11162        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11163            return true;
11164        }
11165
11166        int perm = checkComponentPermission(
11167                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11168                sourceUid, -1, true);
11169        if (perm == PackageManager.PERMISSION_GRANTED) {
11170            return true;
11171        }
11172
11173        // If the actual IPC caller is different from the logical source, then
11174        // also see if they are allowed to control app switches.
11175        if (callingUid != -1 && callingUid != sourceUid) {
11176            perm = checkComponentPermission(
11177                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11178                    callingUid, -1, true);
11179            if (perm == PackageManager.PERMISSION_GRANTED) {
11180                return true;
11181            }
11182        }
11183
11184        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11185        return false;
11186    }
11187
11188    public void setDebugApp(String packageName, boolean waitForDebugger,
11189            boolean persistent) {
11190        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11191                "setDebugApp()");
11192
11193        long ident = Binder.clearCallingIdentity();
11194        try {
11195            // Note that this is not really thread safe if there are multiple
11196            // callers into it at the same time, but that's not a situation we
11197            // care about.
11198            if (persistent) {
11199                final ContentResolver resolver = mContext.getContentResolver();
11200                Settings.Global.putString(
11201                    resolver, Settings.Global.DEBUG_APP,
11202                    packageName);
11203                Settings.Global.putInt(
11204                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11205                    waitForDebugger ? 1 : 0);
11206            }
11207
11208            synchronized (this) {
11209                if (!persistent) {
11210                    mOrigDebugApp = mDebugApp;
11211                    mOrigWaitForDebugger = mWaitForDebugger;
11212                }
11213                mDebugApp = packageName;
11214                mWaitForDebugger = waitForDebugger;
11215                mDebugTransient = !persistent;
11216                if (packageName != null) {
11217                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11218                            false, UserHandle.USER_ALL, "set debug app");
11219                }
11220            }
11221        } finally {
11222            Binder.restoreCallingIdentity(ident);
11223        }
11224    }
11225
11226    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11227        synchronized (this) {
11228            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11229            if (!isDebuggable) {
11230                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11231                    throw new SecurityException("Process not debuggable: " + app.packageName);
11232                }
11233            }
11234
11235            mTrackAllocationApp = processName;
11236        }
11237    }
11238
11239    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11240        synchronized (this) {
11241            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11242            if (!isDebuggable) {
11243                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11244                    throw new SecurityException("Process not debuggable: " + app.packageName);
11245                }
11246            }
11247            mProfileApp = processName;
11248            mProfileFile = profilerInfo.profileFile;
11249            if (mProfileFd != null) {
11250                try {
11251                    mProfileFd.close();
11252                } catch (IOException e) {
11253                }
11254                mProfileFd = null;
11255            }
11256            mProfileFd = profilerInfo.profileFd;
11257            mSamplingInterval = profilerInfo.samplingInterval;
11258            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11259            mProfileType = 0;
11260        }
11261    }
11262
11263    @Override
11264    public void setAlwaysFinish(boolean enabled) {
11265        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11266                "setAlwaysFinish()");
11267
11268        Settings.Global.putInt(
11269                mContext.getContentResolver(),
11270                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11271
11272        synchronized (this) {
11273            mAlwaysFinishActivities = enabled;
11274        }
11275    }
11276
11277    @Override
11278    public void setActivityController(IActivityController controller) {
11279        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11280                "setActivityController()");
11281        synchronized (this) {
11282            mController = controller;
11283            Watchdog.getInstance().setActivityController(controller);
11284        }
11285    }
11286
11287    @Override
11288    public void setUserIsMonkey(boolean userIsMonkey) {
11289        synchronized (this) {
11290            synchronized (mPidsSelfLocked) {
11291                final int callingPid = Binder.getCallingPid();
11292                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11293                if (precessRecord == null) {
11294                    throw new SecurityException("Unknown process: " + callingPid);
11295                }
11296                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11297                    throw new SecurityException("Only an instrumentation process "
11298                            + "with a UiAutomation can call setUserIsMonkey");
11299                }
11300            }
11301            mUserIsMonkey = userIsMonkey;
11302        }
11303    }
11304
11305    @Override
11306    public boolean isUserAMonkey() {
11307        synchronized (this) {
11308            // If there is a controller also implies the user is a monkey.
11309            return (mUserIsMonkey || mController != null);
11310        }
11311    }
11312
11313    public void requestBugReport(int bugreportType) {
11314        String service = null;
11315        switch (bugreportType) {
11316            case ActivityManager.BUGREPORT_OPTION_FULL:
11317                service = "bugreport";
11318                break;
11319            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11320                service = "bugreportplus";
11321                break;
11322            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11323                service = "bugreportremote";
11324                break;
11325        }
11326        if (service == null) {
11327            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11328                    + bugreportType);
11329        }
11330        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11331        SystemProperties.set("ctl.start", service);
11332    }
11333
11334    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11335        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11336    }
11337
11338    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11339        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11340            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11341        }
11342        return KEY_DISPATCHING_TIMEOUT;
11343    }
11344
11345    @Override
11346    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11347        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11348                != PackageManager.PERMISSION_GRANTED) {
11349            throw new SecurityException("Requires permission "
11350                    + android.Manifest.permission.FILTER_EVENTS);
11351        }
11352        ProcessRecord proc;
11353        long timeout;
11354        synchronized (this) {
11355            synchronized (mPidsSelfLocked) {
11356                proc = mPidsSelfLocked.get(pid);
11357            }
11358            timeout = getInputDispatchingTimeoutLocked(proc);
11359        }
11360
11361        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11362            return -1;
11363        }
11364
11365        return timeout;
11366    }
11367
11368    /**
11369     * Handle input dispatching timeouts.
11370     * Returns whether input dispatching should be aborted or not.
11371     */
11372    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11373            final ActivityRecord activity, final ActivityRecord parent,
11374            final boolean aboveSystem, String reason) {
11375        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11376                != PackageManager.PERMISSION_GRANTED) {
11377            throw new SecurityException("Requires permission "
11378                    + android.Manifest.permission.FILTER_EVENTS);
11379        }
11380
11381        final String annotation;
11382        if (reason == null) {
11383            annotation = "Input dispatching timed out";
11384        } else {
11385            annotation = "Input dispatching timed out (" + reason + ")";
11386        }
11387
11388        if (proc != null) {
11389            synchronized (this) {
11390                if (proc.debugging) {
11391                    return false;
11392                }
11393
11394                if (mDidDexOpt) {
11395                    // Give more time since we were dexopting.
11396                    mDidDexOpt = false;
11397                    return false;
11398                }
11399
11400                if (proc.instrumentationClass != null) {
11401                    Bundle info = new Bundle();
11402                    info.putString("shortMsg", "keyDispatchingTimedOut");
11403                    info.putString("longMsg", annotation);
11404                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11405                    return true;
11406                }
11407            }
11408            mHandler.post(new Runnable() {
11409                @Override
11410                public void run() {
11411                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11412                }
11413            });
11414        }
11415
11416        return true;
11417    }
11418
11419    @Override
11420    public Bundle getAssistContextExtras(int requestType) {
11421        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11422                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11423        if (pae == null) {
11424            return null;
11425        }
11426        synchronized (pae) {
11427            while (!pae.haveResult) {
11428                try {
11429                    pae.wait();
11430                } catch (InterruptedException e) {
11431                }
11432            }
11433        }
11434        synchronized (this) {
11435            buildAssistBundleLocked(pae, pae.result);
11436            mPendingAssistExtras.remove(pae);
11437            mUiHandler.removeCallbacks(pae);
11438        }
11439        return pae.extras;
11440    }
11441
11442    @Override
11443    public boolean isAssistDataAllowedOnCurrentActivity() {
11444        int userId;
11445        synchronized (this) {
11446            userId = mUserController.getCurrentUserIdLocked();
11447            ActivityRecord activity = getFocusedStack().topActivity();
11448            if (activity == null) {
11449                return false;
11450            }
11451            userId = activity.userId;
11452        }
11453        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11454                Context.DEVICE_POLICY_SERVICE);
11455        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11456    }
11457
11458    @Override
11459    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11460        long ident = Binder.clearCallingIdentity();
11461        try {
11462            synchronized (this) {
11463                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11464                ActivityRecord top = getFocusedStack().topActivity();
11465                if (top != caller) {
11466                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11467                            + " is not current top " + top);
11468                    return false;
11469                }
11470                if (!top.nowVisible) {
11471                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11472                            + " is not visible");
11473                    return false;
11474                }
11475            }
11476            AssistUtils utils = new AssistUtils(mContext);
11477            return utils.showSessionForActiveService(args,
11478                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11479        } finally {
11480            Binder.restoreCallingIdentity(ident);
11481        }
11482    }
11483
11484    @Override
11485    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11486            IBinder activityToken) {
11487        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11488                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11489    }
11490
11491    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11492            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11493            long timeout) {
11494        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11495                "enqueueAssistContext()");
11496        synchronized (this) {
11497            ActivityRecord activity = getFocusedStack().topActivity();
11498            if (activity == null) {
11499                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11500                return null;
11501            }
11502            if (activity.app == null || activity.app.thread == null) {
11503                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11504                return null;
11505            }
11506            if (activityToken != null) {
11507                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11508                if (activity != caller) {
11509                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11510                            + " is not current top " + activity);
11511                    return null;
11512                }
11513            }
11514            PendingAssistExtras pae;
11515            Bundle extras = new Bundle();
11516            if (args != null) {
11517                extras.putAll(args);
11518            }
11519            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11520            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11521            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11522            try {
11523                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11524                        requestType);
11525                mPendingAssistExtras.add(pae);
11526                mUiHandler.postDelayed(pae, timeout);
11527            } catch (RemoteException e) {
11528                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11529                return null;
11530            }
11531            return pae;
11532        }
11533    }
11534
11535    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11536        IResultReceiver receiver;
11537        synchronized (this) {
11538            mPendingAssistExtras.remove(pae);
11539            receiver = pae.receiver;
11540        }
11541        if (receiver != null) {
11542            // Caller wants result sent back to them.
11543            try {
11544                pae.receiver.send(0, null);
11545            } catch (RemoteException e) {
11546            }
11547        }
11548    }
11549
11550    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11551        if (result != null) {
11552            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11553        }
11554        if (pae.hint != null) {
11555            pae.extras.putBoolean(pae.hint, true);
11556        }
11557    }
11558
11559    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11560            AssistContent content, Uri referrer) {
11561        PendingAssistExtras pae = (PendingAssistExtras)token;
11562        synchronized (pae) {
11563            pae.result = extras;
11564            pae.structure = structure;
11565            pae.content = content;
11566            if (referrer != null) {
11567                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11568            }
11569            pae.haveResult = true;
11570            pae.notifyAll();
11571            if (pae.intent == null && pae.receiver == null) {
11572                // Caller is just waiting for the result.
11573                return;
11574            }
11575        }
11576
11577        // We are now ready to launch the assist activity.
11578        IResultReceiver sendReceiver = null;
11579        Bundle sendBundle = null;
11580        synchronized (this) {
11581            buildAssistBundleLocked(pae, extras);
11582            boolean exists = mPendingAssistExtras.remove(pae);
11583            mUiHandler.removeCallbacks(pae);
11584            if (!exists) {
11585                // Timed out.
11586                return;
11587            }
11588            if ((sendReceiver=pae.receiver) != null) {
11589                // Caller wants result sent back to them.
11590                sendBundle = new Bundle();
11591                sendBundle.putBundle("data", pae.extras);
11592                sendBundle.putParcelable("structure", pae.structure);
11593                sendBundle.putParcelable("content", pae.content);
11594            }
11595        }
11596        if (sendReceiver != null) {
11597            try {
11598                sendReceiver.send(0, sendBundle);
11599            } catch (RemoteException e) {
11600            }
11601            return;
11602        }
11603
11604        long ident = Binder.clearCallingIdentity();
11605        try {
11606            pae.intent.replaceExtras(pae.extras);
11607            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11608                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11609                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11610            closeSystemDialogs("assist");
11611            try {
11612                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11613            } catch (ActivityNotFoundException e) {
11614                Slog.w(TAG, "No activity to handle assist action.", e);
11615            }
11616        } finally {
11617            Binder.restoreCallingIdentity(ident);
11618        }
11619    }
11620
11621    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11622            Bundle args) {
11623        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11624                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11625    }
11626
11627    public void registerProcessObserver(IProcessObserver observer) {
11628        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11629                "registerProcessObserver()");
11630        synchronized (this) {
11631            mProcessObservers.register(observer);
11632        }
11633    }
11634
11635    @Override
11636    public void unregisterProcessObserver(IProcessObserver observer) {
11637        synchronized (this) {
11638            mProcessObservers.unregister(observer);
11639        }
11640    }
11641
11642    @Override
11643    public void registerUidObserver(IUidObserver observer, int which) {
11644        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11645                "registerUidObserver()");
11646        synchronized (this) {
11647            mUidObservers.register(observer, which);
11648        }
11649    }
11650
11651    @Override
11652    public void unregisterUidObserver(IUidObserver observer) {
11653        synchronized (this) {
11654            mUidObservers.unregister(observer);
11655        }
11656    }
11657
11658    @Override
11659    public boolean convertFromTranslucent(IBinder token) {
11660        final long origId = Binder.clearCallingIdentity();
11661        try {
11662            synchronized (this) {
11663                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11664                if (r == null) {
11665                    return false;
11666                }
11667                final boolean translucentChanged = r.changeWindowTranslucency(true);
11668                if (translucentChanged) {
11669                    r.task.stack.releaseBackgroundResources(r);
11670                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11671                }
11672                mWindowManager.setAppFullscreen(token, true);
11673                return translucentChanged;
11674            }
11675        } finally {
11676            Binder.restoreCallingIdentity(origId);
11677        }
11678    }
11679
11680    @Override
11681    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11682        final long origId = Binder.clearCallingIdentity();
11683        try {
11684            synchronized (this) {
11685                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11686                if (r == null) {
11687                    return false;
11688                }
11689                int index = r.task.mActivities.lastIndexOf(r);
11690                if (index > 0) {
11691                    ActivityRecord under = r.task.mActivities.get(index - 1);
11692                    under.returningOptions = options;
11693                }
11694                final boolean translucentChanged = r.changeWindowTranslucency(false);
11695                if (translucentChanged) {
11696                    r.task.stack.convertActivityToTranslucent(r);
11697                }
11698                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11699                mWindowManager.setAppFullscreen(token, false);
11700                return translucentChanged;
11701            }
11702        } finally {
11703            Binder.restoreCallingIdentity(origId);
11704        }
11705    }
11706
11707    @Override
11708    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11709        final long origId = Binder.clearCallingIdentity();
11710        try {
11711            synchronized (this) {
11712                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11713                if (r != null) {
11714                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11715                }
11716            }
11717            return false;
11718        } finally {
11719            Binder.restoreCallingIdentity(origId);
11720        }
11721    }
11722
11723    @Override
11724    public boolean isBackgroundVisibleBehind(IBinder token) {
11725        final long origId = Binder.clearCallingIdentity();
11726        try {
11727            synchronized (this) {
11728                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11729                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11730                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11731                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11732                return visible;
11733            }
11734        } finally {
11735            Binder.restoreCallingIdentity(origId);
11736        }
11737    }
11738
11739    @Override
11740    public ActivityOptions getActivityOptions(IBinder token) {
11741        final long origId = Binder.clearCallingIdentity();
11742        try {
11743            synchronized (this) {
11744                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11745                if (r != null) {
11746                    final ActivityOptions activityOptions = r.pendingOptions;
11747                    r.pendingOptions = null;
11748                    return activityOptions;
11749                }
11750                return null;
11751            }
11752        } finally {
11753            Binder.restoreCallingIdentity(origId);
11754        }
11755    }
11756
11757    @Override
11758    public void setImmersive(IBinder token, boolean immersive) {
11759        synchronized(this) {
11760            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11761            if (r == null) {
11762                throw new IllegalArgumentException();
11763            }
11764            r.immersive = immersive;
11765
11766            // update associated state if we're frontmost
11767            if (r == mFocusedActivity) {
11768                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11769                applyUpdateLockStateLocked(r);
11770            }
11771        }
11772    }
11773
11774    @Override
11775    public boolean isImmersive(IBinder token) {
11776        synchronized (this) {
11777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11778            if (r == null) {
11779                throw new IllegalArgumentException();
11780            }
11781            return r.immersive;
11782        }
11783    }
11784
11785    @Override
11786    public void setVrMode(IBinder token, boolean enabled) {
11787        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11788            throw new UnsupportedOperationException("VR mode not supported on this device!");
11789        }
11790
11791        synchronized(this) {
11792            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11793            if (r == null) {
11794                throw new IllegalArgumentException();
11795            }
11796            r.isVrActivity = enabled;
11797
11798            // Update associated state if this activity is currently focused
11799            if (r == mFocusedActivity) {
11800                applyUpdateVrModeLocked(r);
11801            }
11802        }
11803    }
11804
11805    public boolean isTopActivityImmersive() {
11806        enforceNotIsolatedCaller("startActivity");
11807        synchronized (this) {
11808            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11809            return (r != null) ? r.immersive : false;
11810        }
11811    }
11812
11813    @Override
11814    public boolean isTopOfTask(IBinder token) {
11815        synchronized (this) {
11816            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11817            if (r == null) {
11818                throw new IllegalArgumentException();
11819            }
11820            return r.task.getTopActivity() == r;
11821        }
11822    }
11823
11824    public final void enterSafeMode() {
11825        synchronized(this) {
11826            // It only makes sense to do this before the system is ready
11827            // and started launching other packages.
11828            if (!mSystemReady) {
11829                try {
11830                    AppGlobals.getPackageManager().enterSafeMode();
11831                } catch (RemoteException e) {
11832                }
11833            }
11834
11835            mSafeMode = true;
11836        }
11837    }
11838
11839    public final void showSafeModeOverlay() {
11840        View v = LayoutInflater.from(mContext).inflate(
11841                com.android.internal.R.layout.safe_mode, null);
11842        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11843        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11844        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11845        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11846        lp.gravity = Gravity.BOTTOM | Gravity.START;
11847        lp.format = v.getBackground().getOpacity();
11848        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11849                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11850        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11851        ((WindowManager)mContext.getSystemService(
11852                Context.WINDOW_SERVICE)).addView(v, lp);
11853    }
11854
11855    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11856        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11857            return;
11858        }
11859        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11860        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11861        synchronized (stats) {
11862            if (mBatteryStatsService.isOnBattery()) {
11863                mBatteryStatsService.enforceCallingPermission();
11864                int MY_UID = Binder.getCallingUid();
11865                final int uid;
11866                if (sender == null) {
11867                    uid = sourceUid;
11868                } else {
11869                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11870                }
11871                BatteryStatsImpl.Uid.Pkg pkg =
11872                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11873                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11874                pkg.noteWakeupAlarmLocked(tag);
11875            }
11876        }
11877    }
11878
11879    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11880        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11881            return;
11882        }
11883        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11884        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11885        synchronized (stats) {
11886            mBatteryStatsService.enforceCallingPermission();
11887            int MY_UID = Binder.getCallingUid();
11888            final int uid;
11889            if (sender == null) {
11890                uid = sourceUid;
11891            } else {
11892                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11893            }
11894            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11895        }
11896    }
11897
11898    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11899        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11900            return;
11901        }
11902        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11903        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11904        synchronized (stats) {
11905            mBatteryStatsService.enforceCallingPermission();
11906            int MY_UID = Binder.getCallingUid();
11907            final int uid;
11908            if (sender == null) {
11909                uid = sourceUid;
11910            } else {
11911                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11912            }
11913            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11914        }
11915    }
11916
11917    public boolean killPids(int[] pids, String pReason, boolean secure) {
11918        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11919            throw new SecurityException("killPids only available to the system");
11920        }
11921        String reason = (pReason == null) ? "Unknown" : pReason;
11922        // XXX Note: don't acquire main activity lock here, because the window
11923        // manager calls in with its locks held.
11924
11925        boolean killed = false;
11926        synchronized (mPidsSelfLocked) {
11927            int worstType = 0;
11928            for (int i=0; i<pids.length; i++) {
11929                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11930                if (proc != null) {
11931                    int type = proc.setAdj;
11932                    if (type > worstType) {
11933                        worstType = type;
11934                    }
11935                }
11936            }
11937
11938            // If the worst oom_adj is somewhere in the cached proc LRU range,
11939            // then constrain it so we will kill all cached procs.
11940            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11941                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11942                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11943            }
11944
11945            // If this is not a secure call, don't let it kill processes that
11946            // are important.
11947            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11948                worstType = ProcessList.SERVICE_ADJ;
11949            }
11950
11951            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11952            for (int i=0; i<pids.length; i++) {
11953                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11954                if (proc == null) {
11955                    continue;
11956                }
11957                int adj = proc.setAdj;
11958                if (adj >= worstType && !proc.killedByAm) {
11959                    proc.kill(reason, true);
11960                    killed = true;
11961                }
11962            }
11963        }
11964        return killed;
11965    }
11966
11967    @Override
11968    public void killUid(int appId, int userId, String reason) {
11969        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11970        synchronized (this) {
11971            final long identity = Binder.clearCallingIdentity();
11972            try {
11973                killPackageProcessesLocked(null, appId, userId,
11974                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11975                        reason != null ? reason : "kill uid");
11976            } finally {
11977                Binder.restoreCallingIdentity(identity);
11978            }
11979        }
11980    }
11981
11982    @Override
11983    public boolean killProcessesBelowForeground(String reason) {
11984        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11985            throw new SecurityException("killProcessesBelowForeground() only available to system");
11986        }
11987
11988        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11989    }
11990
11991    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11992        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11993            throw new SecurityException("killProcessesBelowAdj() only available to system");
11994        }
11995
11996        boolean killed = false;
11997        synchronized (mPidsSelfLocked) {
11998            final int size = mPidsSelfLocked.size();
11999            for (int i = 0; i < size; i++) {
12000                final int pid = mPidsSelfLocked.keyAt(i);
12001                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12002                if (proc == null) continue;
12003
12004                final int adj = proc.setAdj;
12005                if (adj > belowAdj && !proc.killedByAm) {
12006                    proc.kill(reason, true);
12007                    killed = true;
12008                }
12009            }
12010        }
12011        return killed;
12012    }
12013
12014    @Override
12015    public void hang(final IBinder who, boolean allowRestart) {
12016        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12017                != PackageManager.PERMISSION_GRANTED) {
12018            throw new SecurityException("Requires permission "
12019                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12020        }
12021
12022        final IBinder.DeathRecipient death = new DeathRecipient() {
12023            @Override
12024            public void binderDied() {
12025                synchronized (this) {
12026                    notifyAll();
12027                }
12028            }
12029        };
12030
12031        try {
12032            who.linkToDeath(death, 0);
12033        } catch (RemoteException e) {
12034            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12035            return;
12036        }
12037
12038        synchronized (this) {
12039            Watchdog.getInstance().setAllowRestart(allowRestart);
12040            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12041            synchronized (death) {
12042                while (who.isBinderAlive()) {
12043                    try {
12044                        death.wait();
12045                    } catch (InterruptedException e) {
12046                    }
12047                }
12048            }
12049            Watchdog.getInstance().setAllowRestart(true);
12050        }
12051    }
12052
12053    @Override
12054    public void restart() {
12055        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12056                != PackageManager.PERMISSION_GRANTED) {
12057            throw new SecurityException("Requires permission "
12058                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12059        }
12060
12061        Log.i(TAG, "Sending shutdown broadcast...");
12062
12063        BroadcastReceiver br = new BroadcastReceiver() {
12064            @Override public void onReceive(Context context, Intent intent) {
12065                // Now the broadcast is done, finish up the low-level shutdown.
12066                Log.i(TAG, "Shutting down activity manager...");
12067                shutdown(10000);
12068                Log.i(TAG, "Shutdown complete, restarting!");
12069                Process.killProcess(Process.myPid());
12070                System.exit(10);
12071            }
12072        };
12073
12074        // First send the high-level shut down broadcast.
12075        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12076        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12077        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12078        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12079        mContext.sendOrderedBroadcastAsUser(intent,
12080                UserHandle.ALL, null, br, mHandler, 0, null, null);
12081        */
12082        br.onReceive(mContext, intent);
12083    }
12084
12085    private long getLowRamTimeSinceIdle(long now) {
12086        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12087    }
12088
12089    @Override
12090    public void performIdleMaintenance() {
12091        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12092                != PackageManager.PERMISSION_GRANTED) {
12093            throw new SecurityException("Requires permission "
12094                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12095        }
12096
12097        synchronized (this) {
12098            final long now = SystemClock.uptimeMillis();
12099            final long timeSinceLastIdle = now - mLastIdleTime;
12100            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12101            mLastIdleTime = now;
12102            mLowRamTimeSinceLastIdle = 0;
12103            if (mLowRamStartTime != 0) {
12104                mLowRamStartTime = now;
12105            }
12106
12107            StringBuilder sb = new StringBuilder(128);
12108            sb.append("Idle maintenance over ");
12109            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12110            sb.append(" low RAM for ");
12111            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12112            Slog.i(TAG, sb.toString());
12113
12114            // If at least 1/3 of our time since the last idle period has been spent
12115            // with RAM low, then we want to kill processes.
12116            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12117
12118            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12119                ProcessRecord proc = mLruProcesses.get(i);
12120                if (proc.notCachedSinceIdle) {
12121                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12122                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12123                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12124                        if (doKilling && proc.initialIdlePss != 0
12125                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12126                            sb = new StringBuilder(128);
12127                            sb.append("Kill");
12128                            sb.append(proc.processName);
12129                            sb.append(" in idle maint: pss=");
12130                            sb.append(proc.lastPss);
12131                            sb.append(", swapPss=");
12132                            sb.append(proc.lastSwapPss);
12133                            sb.append(", initialPss=");
12134                            sb.append(proc.initialIdlePss);
12135                            sb.append(", period=");
12136                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12137                            sb.append(", lowRamPeriod=");
12138                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12139                            Slog.wtfQuiet(TAG, sb.toString());
12140                            proc.kill("idle maint (pss " + proc.lastPss
12141                                    + " from " + proc.initialIdlePss + ")", true);
12142                        }
12143                    }
12144                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12145                    proc.notCachedSinceIdle = true;
12146                    proc.initialIdlePss = 0;
12147                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12148                            mTestPssMode, isSleeping(), now);
12149                }
12150            }
12151
12152            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12153            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12154        }
12155    }
12156
12157    private void retrieveSettings() {
12158        final ContentResolver resolver = mContext.getContentResolver();
12159        final boolean freeformWindowManagement =
12160                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12161                        || Settings.Global.getInt(
12162                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12163        final boolean supportsPictureInPicture =
12164                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12165
12166        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12167        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12168        final boolean alwaysFinishActivities =
12169                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12170        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12171        final boolean forceResizable = Settings.Global.getInt(
12172                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12173        // Transfer any global setting for forcing RTL layout, into a System Property
12174        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12175
12176        final Configuration configuration = new Configuration();
12177        Settings.System.getConfiguration(resolver, configuration);
12178        if (forceRtl) {
12179            // This will take care of setting the correct layout direction flags
12180            configuration.setLayoutDirection(configuration.locale);
12181        }
12182
12183        synchronized (this) {
12184            mDebugApp = mOrigDebugApp = debugApp;
12185            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12186            mAlwaysFinishActivities = alwaysFinishActivities;
12187            mForceResizableActivities = forceResizable;
12188            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12189            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12190            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12191            // This happens before any activities are started, so we can
12192            // change mConfiguration in-place.
12193            updateConfigurationLocked(configuration, null, true);
12194            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12195                    "Initial config: " + mConfiguration);
12196
12197            // Load resources only after the current configuration has been set.
12198            final Resources res = mContext.getResources();
12199            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12200            mThumbnailWidth = res.getDimensionPixelSize(
12201                    com.android.internal.R.dimen.thumbnail_width);
12202            mThumbnailHeight = res.getDimensionPixelSize(
12203                    com.android.internal.R.dimen.thumbnail_height);
12204            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12205                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12206            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12207                    com.android.internal.R.string.config_appsNotReportingCrashes));
12208        }
12209    }
12210
12211    public boolean testIsSystemReady() {
12212        // no need to synchronize(this) just to read & return the value
12213        return mSystemReady;
12214    }
12215
12216    private static File getCalledPreBootReceiversFile() {
12217        File dataDir = Environment.getDataDirectory();
12218        File systemDir = new File(dataDir, "system");
12219        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12220        return fname;
12221    }
12222
12223    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12224        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12225        File file = getCalledPreBootReceiversFile();
12226        FileInputStream fis = null;
12227        try {
12228            fis = new FileInputStream(file);
12229            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12230            int fvers = dis.readInt();
12231            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12232                String vers = dis.readUTF();
12233                String codename = dis.readUTF();
12234                String build = dis.readUTF();
12235                if (android.os.Build.VERSION.RELEASE.equals(vers)
12236                        && android.os.Build.VERSION.CODENAME.equals(codename)
12237                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12238                    int num = dis.readInt();
12239                    while (num > 0) {
12240                        num--;
12241                        String pkg = dis.readUTF();
12242                        String cls = dis.readUTF();
12243                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12244                    }
12245                }
12246            }
12247        } catch (FileNotFoundException e) {
12248        } catch (IOException e) {
12249            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12250        } finally {
12251            if (fis != null) {
12252                try {
12253                    fis.close();
12254                } catch (IOException e) {
12255                }
12256            }
12257        }
12258        return lastDoneReceivers;
12259    }
12260
12261    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12262        File file = getCalledPreBootReceiversFile();
12263        FileOutputStream fos = null;
12264        DataOutputStream dos = null;
12265        try {
12266            fos = new FileOutputStream(file);
12267            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12268            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12269            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12270            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12271            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12272            dos.writeInt(list.size());
12273            for (int i=0; i<list.size(); i++) {
12274                dos.writeUTF(list.get(i).getPackageName());
12275                dos.writeUTF(list.get(i).getClassName());
12276            }
12277        } catch (IOException e) {
12278            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12279            file.delete();
12280        } finally {
12281            FileUtils.sync(fos);
12282            if (dos != null) {
12283                try {
12284                    dos.close();
12285                } catch (IOException e) {
12286                    // TODO Auto-generated catch block
12287                    e.printStackTrace();
12288                }
12289            }
12290        }
12291    }
12292
12293    final class PreBootContinuation extends IIntentReceiver.Stub {
12294        final Intent intent;
12295        final Runnable onFinishCallback;
12296        final ArrayList<ComponentName> doneReceivers;
12297        final List<ResolveInfo> ris;
12298        final int[] users;
12299        int lastRi = -1;
12300        int curRi = 0;
12301        int curUser = 0;
12302
12303        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12304                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12305            intent = _intent;
12306            onFinishCallback = _onFinishCallback;
12307            doneReceivers = _doneReceivers;
12308            ris = _ris;
12309            users = _users;
12310        }
12311
12312        void go() {
12313            if (lastRi != curRi) {
12314                ActivityInfo ai = ris.get(curRi).activityInfo;
12315                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12316                intent.setComponent(comp);
12317                doneReceivers.add(comp);
12318                lastRi = curRi;
12319                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12320                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12321            }
12322            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12323                    + " for user " + users[curUser]);
12324            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12325            broadcastIntentLocked(null, null, intent, null, this,
12326                    0, null, null, null, AppOpsManager.OP_NONE,
12327                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12328        }
12329
12330        public void performReceive(Intent intent, int resultCode,
12331                String data, Bundle extras, boolean ordered,
12332                boolean sticky, int sendingUser) {
12333            curUser++;
12334            if (curUser >= users.length) {
12335                curUser = 0;
12336                curRi++;
12337                if (curRi >= ris.size()) {
12338                    // All done sending broadcasts!
12339                    if (onFinishCallback != null) {
12340                        // The raw IIntentReceiver interface is called
12341                        // with the AM lock held, so redispatch to
12342                        // execute our code without the lock.
12343                        mHandler.post(onFinishCallback);
12344                    }
12345                    return;
12346                }
12347            }
12348            go();
12349        }
12350    }
12351
12352    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12353            ArrayList<ComponentName> doneReceivers) {
12354        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12355        List<ResolveInfo> ris = null;
12356        try {
12357            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12358                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
12359        } catch (RemoteException e) {
12360        }
12361        if (ris == null) {
12362            return false;
12363        }
12364        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12365
12366        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12367        for (int i=0; i<ris.size(); i++) {
12368            ActivityInfo ai = ris.get(i).activityInfo;
12369            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12370            if (lastDoneReceivers.contains(comp)) {
12371                // We already did the pre boot receiver for this app with the current
12372                // platform version, so don't do it again...
12373                ris.remove(i);
12374                i--;
12375                // ...however, do keep it as one that has been done, so we don't
12376                // forget about it when rewriting the file of last done receivers.
12377                doneReceivers.add(comp);
12378            }
12379        }
12380
12381        if (ris.size() <= 0) {
12382            return false;
12383        }
12384
12385        // TODO: can we still do this with per user encryption?
12386        final int[] users = mUserController.getUsers();
12387        if (users.length <= 0) {
12388            return false;
12389        }
12390
12391        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12392                ris, users);
12393        cont.go();
12394        return true;
12395    }
12396
12397    public void systemReady(final Runnable goingCallback) {
12398        synchronized(this) {
12399            if (mSystemReady) {
12400                // If we're done calling all the receivers, run the next "boot phase" passed in
12401                // by the SystemServer
12402                if (goingCallback != null) {
12403                    goingCallback.run();
12404                }
12405                return;
12406            }
12407
12408            mLocalDeviceIdleController
12409                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12410
12411            // Make sure we have the current profile info, since it is needed for
12412            // security checks.
12413            mUserController.updateCurrentProfileIdsLocked();
12414
12415            mRecentTasks.onSystemReady();
12416            // Check to see if there are any update receivers to run.
12417            if (!mDidUpdate) {
12418                if (mWaitingUpdate) {
12419                    return;
12420                }
12421                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12422                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12423                    public void run() {
12424                        synchronized (ActivityManagerService.this) {
12425                            mDidUpdate = true;
12426                        }
12427                        showBootMessage(mContext.getText(
12428                                R.string.android_upgrading_complete),
12429                                false);
12430                        writeLastDonePreBootReceivers(doneReceivers);
12431                        systemReady(goingCallback);
12432                    }
12433                }, doneReceivers);
12434
12435                if (mWaitingUpdate) {
12436                    return;
12437                }
12438                mDidUpdate = true;
12439            }
12440
12441            mAppOpsService.systemReady();
12442            mSystemReady = true;
12443        }
12444
12445        ArrayList<ProcessRecord> procsToKill = null;
12446        synchronized(mPidsSelfLocked) {
12447            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12448                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12449                if (!isAllowedWhileBooting(proc.info)){
12450                    if (procsToKill == null) {
12451                        procsToKill = new ArrayList<ProcessRecord>();
12452                    }
12453                    procsToKill.add(proc);
12454                }
12455            }
12456        }
12457
12458        synchronized(this) {
12459            if (procsToKill != null) {
12460                for (int i=procsToKill.size()-1; i>=0; i--) {
12461                    ProcessRecord proc = procsToKill.get(i);
12462                    Slog.i(TAG, "Removing system update proc: " + proc);
12463                    removeProcessLocked(proc, true, false, "system update done");
12464                }
12465            }
12466
12467            // Now that we have cleaned up any update processes, we
12468            // are ready to start launching real processes and know that
12469            // we won't trample on them any more.
12470            mProcessesReady = true;
12471        }
12472
12473        Slog.i(TAG, "System now ready");
12474        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12475            SystemClock.uptimeMillis());
12476
12477        synchronized(this) {
12478            // Make sure we have no pre-ready processes sitting around.
12479
12480            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12481                ResolveInfo ri = mContext.getPackageManager()
12482                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12483                                STOCK_PM_FLAGS);
12484                CharSequence errorMsg = null;
12485                if (ri != null) {
12486                    ActivityInfo ai = ri.activityInfo;
12487                    ApplicationInfo app = ai.applicationInfo;
12488                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12489                        mTopAction = Intent.ACTION_FACTORY_TEST;
12490                        mTopData = null;
12491                        mTopComponent = new ComponentName(app.packageName,
12492                                ai.name);
12493                    } else {
12494                        errorMsg = mContext.getResources().getText(
12495                                com.android.internal.R.string.factorytest_not_system);
12496                    }
12497                } else {
12498                    errorMsg = mContext.getResources().getText(
12499                            com.android.internal.R.string.factorytest_no_action);
12500                }
12501                if (errorMsg != null) {
12502                    mTopAction = null;
12503                    mTopData = null;
12504                    mTopComponent = null;
12505                    Message msg = Message.obtain();
12506                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12507                    msg.getData().putCharSequence("msg", errorMsg);
12508                    mUiHandler.sendMessage(msg);
12509                }
12510            }
12511        }
12512
12513        retrieveSettings();
12514        final int currentUserId;
12515        synchronized (this) {
12516            currentUserId = mUserController.getCurrentUserIdLocked();
12517            readGrantedUriPermissionsLocked();
12518        }
12519
12520        if (goingCallback != null) goingCallback.run();
12521
12522        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12523                Integer.toString(currentUserId), currentUserId);
12524        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12525                Integer.toString(currentUserId), currentUserId);
12526        mSystemServiceManager.startUser(currentUserId);
12527
12528        synchronized (this) {
12529            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12530                try {
12531                    List apps = AppGlobals.getPackageManager().
12532                        getPersistentApplications(STOCK_PM_FLAGS);
12533                    if (apps != null) {
12534                        int N = apps.size();
12535                        int i;
12536                        for (i=0; i<N; i++) {
12537                            ApplicationInfo info
12538                                = (ApplicationInfo)apps.get(i);
12539                            if (info != null &&
12540                                    !info.packageName.equals("android")) {
12541                                addAppLocked(info, false, null /* ABI override */);
12542                            }
12543                        }
12544                    }
12545                } catch (RemoteException ex) {
12546                    // pm is in same process, this will never happen.
12547                }
12548            }
12549
12550            // Start up initial activity.
12551            mBooting = true;
12552            // Enable home activity for system user, so that the system can always boot
12553            if (UserManager.isSplitSystemUser()) {
12554                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12555                try {
12556                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12557                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12558                            UserHandle.USER_SYSTEM);
12559                } catch (RemoteException e) {
12560                    e.rethrowAsRuntimeException();
12561                }
12562            }
12563            startHomeActivityLocked(currentUserId, "systemReady");
12564
12565            try {
12566                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12567                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12568                            + " data partition or your device will be unstable.");
12569                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12570                }
12571            } catch (RemoteException e) {
12572            }
12573
12574            if (!Build.isBuildConsistent()) {
12575                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12576                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12577            }
12578
12579            long ident = Binder.clearCallingIdentity();
12580            try {
12581                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12582                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12583                        | Intent.FLAG_RECEIVER_FOREGROUND);
12584                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12585                broadcastIntentLocked(null, null, intent,
12586                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12587                        null, false, false, MY_PID, Process.SYSTEM_UID,
12588                        currentUserId);
12589                intent = new Intent(Intent.ACTION_USER_STARTING);
12590                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12591                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12592                broadcastIntentLocked(null, null, intent,
12593                        null, new IIntentReceiver.Stub() {
12594                            @Override
12595                            public void performReceive(Intent intent, int resultCode, String data,
12596                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12597                                    throws RemoteException {
12598                            }
12599                        }, 0, null, null,
12600                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12601                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12602            } catch (Throwable t) {
12603                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12604            } finally {
12605                Binder.restoreCallingIdentity(ident);
12606            }
12607            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12608            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12609        }
12610    }
12611
12612    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12613        synchronized (this) {
12614            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12615        }
12616    }
12617
12618    void skipCurrentReceiverLocked(ProcessRecord app) {
12619        for (BroadcastQueue queue : mBroadcastQueues) {
12620            queue.skipCurrentReceiverLocked(app);
12621        }
12622    }
12623
12624    /**
12625     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12626     * The application process will exit immediately after this call returns.
12627     * @param app object of the crashing app, null for the system server
12628     * @param crashInfo describing the exception
12629     */
12630    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12631        ProcessRecord r = findAppProcess(app, "Crash");
12632        final String processName = app == null ? "system_server"
12633                : (r == null ? "unknown" : r.processName);
12634
12635        handleApplicationCrashInner("crash", r, processName, crashInfo);
12636    }
12637
12638    /* Native crash reporting uses this inner version because it needs to be somewhat
12639     * decoupled from the AM-managed cleanup lifecycle
12640     */
12641    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12642            ApplicationErrorReport.CrashInfo crashInfo) {
12643        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12644                UserHandle.getUserId(Binder.getCallingUid()), processName,
12645                r == null ? -1 : r.info.flags,
12646                crashInfo.exceptionClassName,
12647                crashInfo.exceptionMessage,
12648                crashInfo.throwFileName,
12649                crashInfo.throwLineNumber);
12650
12651        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12652
12653        mAppErrors.crashApplication(r, crashInfo);
12654    }
12655
12656    public void handleApplicationStrictModeViolation(
12657            IBinder app,
12658            int violationMask,
12659            StrictMode.ViolationInfo info) {
12660        ProcessRecord r = findAppProcess(app, "StrictMode");
12661        if (r == null) {
12662            return;
12663        }
12664
12665        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12666            Integer stackFingerprint = info.hashCode();
12667            boolean logIt = true;
12668            synchronized (mAlreadyLoggedViolatedStacks) {
12669                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12670                    logIt = false;
12671                    // TODO: sub-sample into EventLog for these, with
12672                    // the info.durationMillis?  Then we'd get
12673                    // the relative pain numbers, without logging all
12674                    // the stack traces repeatedly.  We'd want to do
12675                    // likewise in the client code, which also does
12676                    // dup suppression, before the Binder call.
12677                } else {
12678                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12679                        mAlreadyLoggedViolatedStacks.clear();
12680                    }
12681                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12682                }
12683            }
12684            if (logIt) {
12685                logStrictModeViolationToDropBox(r, info);
12686            }
12687        }
12688
12689        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12690            AppErrorResult result = new AppErrorResult();
12691            synchronized (this) {
12692                final long origId = Binder.clearCallingIdentity();
12693
12694                Message msg = Message.obtain();
12695                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12696                HashMap<String, Object> data = new HashMap<String, Object>();
12697                data.put("result", result);
12698                data.put("app", r);
12699                data.put("violationMask", violationMask);
12700                data.put("info", info);
12701                msg.obj = data;
12702                mUiHandler.sendMessage(msg);
12703
12704                Binder.restoreCallingIdentity(origId);
12705            }
12706            int res = result.get();
12707            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12708        }
12709    }
12710
12711    // Depending on the policy in effect, there could be a bunch of
12712    // these in quick succession so we try to batch these together to
12713    // minimize disk writes, number of dropbox entries, and maximize
12714    // compression, by having more fewer, larger records.
12715    private void logStrictModeViolationToDropBox(
12716            ProcessRecord process,
12717            StrictMode.ViolationInfo info) {
12718        if (info == null) {
12719            return;
12720        }
12721        final boolean isSystemApp = process == null ||
12722                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12723                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12724        final String processName = process == null ? "unknown" : process.processName;
12725        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12726        final DropBoxManager dbox = (DropBoxManager)
12727                mContext.getSystemService(Context.DROPBOX_SERVICE);
12728
12729        // Exit early if the dropbox isn't configured to accept this report type.
12730        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12731
12732        boolean bufferWasEmpty;
12733        boolean needsFlush;
12734        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12735        synchronized (sb) {
12736            bufferWasEmpty = sb.length() == 0;
12737            appendDropBoxProcessHeaders(process, processName, sb);
12738            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12739            sb.append("System-App: ").append(isSystemApp).append("\n");
12740            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12741            if (info.violationNumThisLoop != 0) {
12742                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12743            }
12744            if (info.numAnimationsRunning != 0) {
12745                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12746            }
12747            if (info.broadcastIntentAction != null) {
12748                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12749            }
12750            if (info.durationMillis != -1) {
12751                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12752            }
12753            if (info.numInstances != -1) {
12754                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12755            }
12756            if (info.tags != null) {
12757                for (String tag : info.tags) {
12758                    sb.append("Span-Tag: ").append(tag).append("\n");
12759                }
12760            }
12761            sb.append("\n");
12762            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12763                sb.append(info.crashInfo.stackTrace);
12764                sb.append("\n");
12765            }
12766            if (info.message != null) {
12767                sb.append(info.message);
12768                sb.append("\n");
12769            }
12770
12771            // Only buffer up to ~64k.  Various logging bits truncate
12772            // things at 128k.
12773            needsFlush = (sb.length() > 64 * 1024);
12774        }
12775
12776        // Flush immediately if the buffer's grown too large, or this
12777        // is a non-system app.  Non-system apps are isolated with a
12778        // different tag & policy and not batched.
12779        //
12780        // Batching is useful during internal testing with
12781        // StrictMode settings turned up high.  Without batching,
12782        // thousands of separate files could be created on boot.
12783        if (!isSystemApp || needsFlush) {
12784            new Thread("Error dump: " + dropboxTag) {
12785                @Override
12786                public void run() {
12787                    String report;
12788                    synchronized (sb) {
12789                        report = sb.toString();
12790                        sb.delete(0, sb.length());
12791                        sb.trimToSize();
12792                    }
12793                    if (report.length() != 0) {
12794                        dbox.addText(dropboxTag, report);
12795                    }
12796                }
12797            }.start();
12798            return;
12799        }
12800
12801        // System app batching:
12802        if (!bufferWasEmpty) {
12803            // An existing dropbox-writing thread is outstanding, so
12804            // we don't need to start it up.  The existing thread will
12805            // catch the buffer appends we just did.
12806            return;
12807        }
12808
12809        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12810        // (After this point, we shouldn't access AMS internal data structures.)
12811        new Thread("Error dump: " + dropboxTag) {
12812            @Override
12813            public void run() {
12814                // 5 second sleep to let stacks arrive and be batched together
12815                try {
12816                    Thread.sleep(5000);  // 5 seconds
12817                } catch (InterruptedException e) {}
12818
12819                String errorReport;
12820                synchronized (mStrictModeBuffer) {
12821                    errorReport = mStrictModeBuffer.toString();
12822                    if (errorReport.length() == 0) {
12823                        return;
12824                    }
12825                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12826                    mStrictModeBuffer.trimToSize();
12827                }
12828                dbox.addText(dropboxTag, errorReport);
12829            }
12830        }.start();
12831    }
12832
12833    /**
12834     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12835     * @param app object of the crashing app, null for the system server
12836     * @param tag reported by the caller
12837     * @param system whether this wtf is coming from the system
12838     * @param crashInfo describing the context of the error
12839     * @return true if the process should exit immediately (WTF is fatal)
12840     */
12841    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12842            final ApplicationErrorReport.CrashInfo crashInfo) {
12843        final int callingUid = Binder.getCallingUid();
12844        final int callingPid = Binder.getCallingPid();
12845
12846        if (system) {
12847            // If this is coming from the system, we could very well have low-level
12848            // system locks held, so we want to do this all asynchronously.  And we
12849            // never want this to become fatal, so there is that too.
12850            mHandler.post(new Runnable() {
12851                @Override public void run() {
12852                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12853                }
12854            });
12855            return false;
12856        }
12857
12858        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12859                crashInfo);
12860
12861        if (r != null && r.pid != Process.myPid() &&
12862                Settings.Global.getInt(mContext.getContentResolver(),
12863                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12864            mAppErrors.crashApplication(r, crashInfo);
12865            return true;
12866        } else {
12867            return false;
12868        }
12869    }
12870
12871    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12872            final ApplicationErrorReport.CrashInfo crashInfo) {
12873        final ProcessRecord r = findAppProcess(app, "WTF");
12874        final String processName = app == null ? "system_server"
12875                : (r == null ? "unknown" : r.processName);
12876
12877        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12878                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12879
12880        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12881
12882        return r;
12883    }
12884
12885    /**
12886     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12887     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12888     */
12889    private ProcessRecord findAppProcess(IBinder app, String reason) {
12890        if (app == null) {
12891            return null;
12892        }
12893
12894        synchronized (this) {
12895            final int NP = mProcessNames.getMap().size();
12896            for (int ip=0; ip<NP; ip++) {
12897                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12898                final int NA = apps.size();
12899                for (int ia=0; ia<NA; ia++) {
12900                    ProcessRecord p = apps.valueAt(ia);
12901                    if (p.thread != null && p.thread.asBinder() == app) {
12902                        return p;
12903                    }
12904                }
12905            }
12906
12907            Slog.w(TAG, "Can't find mystery application for " + reason
12908                    + " from pid=" + Binder.getCallingPid()
12909                    + " uid=" + Binder.getCallingUid() + ": " + app);
12910            return null;
12911        }
12912    }
12913
12914    /**
12915     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12916     * to append various headers to the dropbox log text.
12917     */
12918    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12919            StringBuilder sb) {
12920        // Watchdog thread ends up invoking this function (with
12921        // a null ProcessRecord) to add the stack file to dropbox.
12922        // Do not acquire a lock on this (am) in such cases, as it
12923        // could cause a potential deadlock, if and when watchdog
12924        // is invoked due to unavailability of lock on am and it
12925        // would prevent watchdog from killing system_server.
12926        if (process == null) {
12927            sb.append("Process: ").append(processName).append("\n");
12928            return;
12929        }
12930        // Note: ProcessRecord 'process' is guarded by the service
12931        // instance.  (notably process.pkgList, which could otherwise change
12932        // concurrently during execution of this method)
12933        synchronized (this) {
12934            sb.append("Process: ").append(processName).append("\n");
12935            int flags = process.info.flags;
12936            IPackageManager pm = AppGlobals.getPackageManager();
12937            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12938            for (int ip=0; ip<process.pkgList.size(); ip++) {
12939                String pkg = process.pkgList.keyAt(ip);
12940                sb.append("Package: ").append(pkg);
12941                try {
12942                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12943                    if (pi != null) {
12944                        sb.append(" v").append(pi.versionCode);
12945                        if (pi.versionName != null) {
12946                            sb.append(" (").append(pi.versionName).append(")");
12947                        }
12948                    }
12949                } catch (RemoteException e) {
12950                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12951                }
12952                sb.append("\n");
12953            }
12954        }
12955    }
12956
12957    private static String processClass(ProcessRecord process) {
12958        if (process == null || process.pid == MY_PID) {
12959            return "system_server";
12960        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12961            return "system_app";
12962        } else {
12963            return "data_app";
12964        }
12965    }
12966
12967    /**
12968     * Write a description of an error (crash, WTF, ANR) to the drop box.
12969     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12970     * @param process which caused the error, null means the system server
12971     * @param activity which triggered the error, null if unknown
12972     * @param parent activity related to the error, null if unknown
12973     * @param subject line related to the error, null if absent
12974     * @param report in long form describing the error, null if absent
12975     * @param logFile to include in the report, null if none
12976     * @param crashInfo giving an application stack trace, null if absent
12977     */
12978    public void addErrorToDropBox(String eventType,
12979            ProcessRecord process, String processName, ActivityRecord activity,
12980            ActivityRecord parent, String subject,
12981            final String report, final File logFile,
12982            final ApplicationErrorReport.CrashInfo crashInfo) {
12983        // NOTE -- this must never acquire the ActivityManagerService lock,
12984        // otherwise the watchdog may be prevented from resetting the system.
12985
12986        final String dropboxTag = processClass(process) + "_" + eventType;
12987        final DropBoxManager dbox = (DropBoxManager)
12988                mContext.getSystemService(Context.DROPBOX_SERVICE);
12989
12990        // Exit early if the dropbox isn't configured to accept this report type.
12991        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12992
12993        final StringBuilder sb = new StringBuilder(1024);
12994        appendDropBoxProcessHeaders(process, processName, sb);
12995        if (process != null) {
12996            sb.append("Foreground: ")
12997                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
12998                    .append("\n");
12999        }
13000        if (activity != null) {
13001            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13002        }
13003        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13004            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13005        }
13006        if (parent != null && parent != activity) {
13007            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13008        }
13009        if (subject != null) {
13010            sb.append("Subject: ").append(subject).append("\n");
13011        }
13012        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13013        if (Debug.isDebuggerConnected()) {
13014            sb.append("Debugger: Connected\n");
13015        }
13016        sb.append("\n");
13017
13018        // Do the rest in a worker thread to avoid blocking the caller on I/O
13019        // (After this point, we shouldn't access AMS internal data structures.)
13020        Thread worker = new Thread("Error dump: " + dropboxTag) {
13021            @Override
13022            public void run() {
13023                if (report != null) {
13024                    sb.append(report);
13025                }
13026                if (logFile != null) {
13027                    try {
13028                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13029                                    "\n\n[[TRUNCATED]]"));
13030                    } catch (IOException e) {
13031                        Slog.e(TAG, "Error reading " + logFile, e);
13032                    }
13033                }
13034                if (crashInfo != null && crashInfo.stackTrace != null) {
13035                    sb.append(crashInfo.stackTrace);
13036                }
13037
13038                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13039                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13040                if (lines > 0) {
13041                    sb.append("\n");
13042
13043                    // Merge several logcat streams, and take the last N lines
13044                    InputStreamReader input = null;
13045                    try {
13046                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13047                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13048                                "-b", "crash",
13049                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13050
13051                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13052                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13053                        input = new InputStreamReader(logcat.getInputStream());
13054
13055                        int num;
13056                        char[] buf = new char[8192];
13057                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13058                    } catch (IOException e) {
13059                        Slog.e(TAG, "Error running logcat", e);
13060                    } finally {
13061                        if (input != null) try { input.close(); } catch (IOException e) {}
13062                    }
13063                }
13064
13065                dbox.addText(dropboxTag, sb.toString());
13066            }
13067        };
13068
13069        if (process == null) {
13070            // If process is null, we are being called from some internal code
13071            // and may be about to die -- run this synchronously.
13072            worker.run();
13073        } else {
13074            worker.start();
13075        }
13076    }
13077
13078    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13079        enforceNotIsolatedCaller("getProcessesInErrorState");
13080        // assume our apps are happy - lazy create the list
13081        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13082
13083        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13084                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13085        int userId = UserHandle.getUserId(Binder.getCallingUid());
13086
13087        synchronized (this) {
13088
13089            // iterate across all processes
13090            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13091                ProcessRecord app = mLruProcesses.get(i);
13092                if (!allUsers && app.userId != userId) {
13093                    continue;
13094                }
13095                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13096                    // This one's in trouble, so we'll generate a report for it
13097                    // crashes are higher priority (in case there's a crash *and* an anr)
13098                    ActivityManager.ProcessErrorStateInfo report = null;
13099                    if (app.crashing) {
13100                        report = app.crashingReport;
13101                    } else if (app.notResponding) {
13102                        report = app.notRespondingReport;
13103                    }
13104
13105                    if (report != null) {
13106                        if (errList == null) {
13107                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13108                        }
13109                        errList.add(report);
13110                    } else {
13111                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13112                                " crashing = " + app.crashing +
13113                                " notResponding = " + app.notResponding);
13114                    }
13115                }
13116            }
13117        }
13118
13119        return errList;
13120    }
13121
13122    static int procStateToImportance(int procState, int memAdj,
13123            ActivityManager.RunningAppProcessInfo currApp) {
13124        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13125        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13126            currApp.lru = memAdj;
13127        } else {
13128            currApp.lru = 0;
13129        }
13130        return imp;
13131    }
13132
13133    private void fillInProcMemInfo(ProcessRecord app,
13134            ActivityManager.RunningAppProcessInfo outInfo) {
13135        outInfo.pid = app.pid;
13136        outInfo.uid = app.info.uid;
13137        if (mHeavyWeightProcess == app) {
13138            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13139        }
13140        if (app.persistent) {
13141            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13142        }
13143        if (app.activities.size() > 0) {
13144            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13145        }
13146        outInfo.lastTrimLevel = app.trimMemoryLevel;
13147        int adj = app.curAdj;
13148        int procState = app.curProcState;
13149        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13150        outInfo.importanceReasonCode = app.adjTypeCode;
13151        outInfo.processState = app.curProcState;
13152    }
13153
13154    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13155        enforceNotIsolatedCaller("getRunningAppProcesses");
13156
13157        final int callingUid = Binder.getCallingUid();
13158
13159        // Lazy instantiation of list
13160        List<ActivityManager.RunningAppProcessInfo> runList = null;
13161        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13162                callingUid) == PackageManager.PERMISSION_GRANTED;
13163        final int userId = UserHandle.getUserId(callingUid);
13164        final boolean allUids = isGetTasksAllowed(
13165                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13166
13167        synchronized (this) {
13168            // Iterate across all processes
13169            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13170                ProcessRecord app = mLruProcesses.get(i);
13171                if ((!allUsers && app.userId != userId)
13172                        || (!allUids && app.uid != callingUid)) {
13173                    continue;
13174                }
13175                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13176                    // Generate process state info for running application
13177                    ActivityManager.RunningAppProcessInfo currApp =
13178                        new ActivityManager.RunningAppProcessInfo(app.processName,
13179                                app.pid, app.getPackageList());
13180                    fillInProcMemInfo(app, currApp);
13181                    if (app.adjSource instanceof ProcessRecord) {
13182                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13183                        currApp.importanceReasonImportance =
13184                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13185                                        app.adjSourceProcState);
13186                    } else if (app.adjSource instanceof ActivityRecord) {
13187                        ActivityRecord r = (ActivityRecord)app.adjSource;
13188                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13189                    }
13190                    if (app.adjTarget instanceof ComponentName) {
13191                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13192                    }
13193                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13194                    //        + " lru=" + currApp.lru);
13195                    if (runList == null) {
13196                        runList = new ArrayList<>();
13197                    }
13198                    runList.add(currApp);
13199                }
13200            }
13201        }
13202        return runList;
13203    }
13204
13205    public List<ApplicationInfo> getRunningExternalApplications() {
13206        enforceNotIsolatedCaller("getRunningExternalApplications");
13207        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13208        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13209        if (runningApps != null && runningApps.size() > 0) {
13210            Set<String> extList = new HashSet<String>();
13211            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13212                if (app.pkgList != null) {
13213                    for (String pkg : app.pkgList) {
13214                        extList.add(pkg);
13215                    }
13216                }
13217            }
13218            IPackageManager pm = AppGlobals.getPackageManager();
13219            for (String pkg : extList) {
13220                try {
13221                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13222                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13223                        retList.add(info);
13224                    }
13225                } catch (RemoteException e) {
13226                }
13227            }
13228        }
13229        return retList;
13230    }
13231
13232    @Override
13233    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13234        enforceNotIsolatedCaller("getMyMemoryState");
13235        synchronized (this) {
13236            ProcessRecord proc;
13237            synchronized (mPidsSelfLocked) {
13238                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13239            }
13240            fillInProcMemInfo(proc, outInfo);
13241        }
13242    }
13243
13244    @Override
13245    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13246            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13247        (new ActivityManagerShellCommand(this, false)).exec(
13248                this, in, out, err, args, resultReceiver);
13249    }
13250
13251    @Override
13252    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13253        if (checkCallingPermission(android.Manifest.permission.DUMP)
13254                != PackageManager.PERMISSION_GRANTED) {
13255            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13256                    + Binder.getCallingPid()
13257                    + ", uid=" + Binder.getCallingUid()
13258                    + " without permission "
13259                    + android.Manifest.permission.DUMP);
13260            return;
13261        }
13262
13263        boolean dumpAll = false;
13264        boolean dumpClient = false;
13265        String dumpPackage = null;
13266
13267        int opti = 0;
13268        while (opti < args.length) {
13269            String opt = args[opti];
13270            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13271                break;
13272            }
13273            opti++;
13274            if ("-a".equals(opt)) {
13275                dumpAll = true;
13276            } else if ("-c".equals(opt)) {
13277                dumpClient = true;
13278            } else if ("-p".equals(opt)) {
13279                if (opti < args.length) {
13280                    dumpPackage = args[opti];
13281                    opti++;
13282                } else {
13283                    pw.println("Error: -p option requires package argument");
13284                    return;
13285                }
13286                dumpClient = true;
13287            } else if ("-h".equals(opt)) {
13288                ActivityManagerShellCommand.dumpHelp(pw, true);
13289                return;
13290            } else {
13291                pw.println("Unknown argument: " + opt + "; use -h for help");
13292            }
13293        }
13294
13295        long origId = Binder.clearCallingIdentity();
13296        boolean more = false;
13297        // Is the caller requesting to dump a particular piece of data?
13298        if (opti < args.length) {
13299            String cmd = args[opti];
13300            opti++;
13301            if ("activities".equals(cmd) || "a".equals(cmd)) {
13302                synchronized (this) {
13303                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13304                }
13305            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13306                synchronized (this) {
13307                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13308                }
13309            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13310                String[] newArgs;
13311                String name;
13312                if (opti >= args.length) {
13313                    name = null;
13314                    newArgs = EMPTY_STRING_ARRAY;
13315                } else {
13316                    dumpPackage = args[opti];
13317                    opti++;
13318                    newArgs = new String[args.length - opti];
13319                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13320                            args.length - opti);
13321                }
13322                synchronized (this) {
13323                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13324                }
13325            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13326                String[] newArgs;
13327                String name;
13328                if (opti >= args.length) {
13329                    name = null;
13330                    newArgs = EMPTY_STRING_ARRAY;
13331                } else {
13332                    dumpPackage = args[opti];
13333                    opti++;
13334                    newArgs = new String[args.length - opti];
13335                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13336                            args.length - opti);
13337                }
13338                synchronized (this) {
13339                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13340                }
13341            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13342                String[] newArgs;
13343                String name;
13344                if (opti >= args.length) {
13345                    name = null;
13346                    newArgs = EMPTY_STRING_ARRAY;
13347                } else {
13348                    dumpPackage = args[opti];
13349                    opti++;
13350                    newArgs = new String[args.length - opti];
13351                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13352                            args.length - opti);
13353                }
13354                synchronized (this) {
13355                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13356                }
13357            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13358                synchronized (this) {
13359                    dumpOomLocked(fd, pw, args, opti, true);
13360                }
13361            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13362                synchronized (this) {
13363                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13364                }
13365            } else if ("provider".equals(cmd)) {
13366                String[] newArgs;
13367                String name;
13368                if (opti >= args.length) {
13369                    name = null;
13370                    newArgs = EMPTY_STRING_ARRAY;
13371                } else {
13372                    name = args[opti];
13373                    opti++;
13374                    newArgs = new String[args.length - opti];
13375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13376                }
13377                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13378                    pw.println("No providers match: " + name);
13379                    pw.println("Use -h for help.");
13380                }
13381            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13382                synchronized (this) {
13383                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13384                }
13385            } else if ("service".equals(cmd)) {
13386                String[] newArgs;
13387                String name;
13388                if (opti >= args.length) {
13389                    name = null;
13390                    newArgs = EMPTY_STRING_ARRAY;
13391                } else {
13392                    name = args[opti];
13393                    opti++;
13394                    newArgs = new String[args.length - opti];
13395                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13396                            args.length - opti);
13397                }
13398                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13399                    pw.println("No services match: " + name);
13400                    pw.println("Use -h for help.");
13401                }
13402            } else if ("package".equals(cmd)) {
13403                String[] newArgs;
13404                if (opti >= args.length) {
13405                    pw.println("package: no package name specified");
13406                    pw.println("Use -h for help.");
13407                } else {
13408                    dumpPackage = args[opti];
13409                    opti++;
13410                    newArgs = new String[args.length - opti];
13411                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13412                            args.length - opti);
13413                    args = newArgs;
13414                    opti = 0;
13415                    more = true;
13416                }
13417            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13418                synchronized (this) {
13419                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13420                }
13421            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13422                synchronized (this) {
13423                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13424                }
13425            } else {
13426                // Dumping a single activity?
13427                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13428                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13429                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13430                    if (res < 0) {
13431                        pw.println("Bad activity command, or no activities match: " + cmd);
13432                        pw.println("Use -h for help.");
13433                    }
13434                }
13435            }
13436            if (!more) {
13437                Binder.restoreCallingIdentity(origId);
13438                return;
13439            }
13440        }
13441
13442        // No piece of data specified, dump everything.
13443        synchronized (this) {
13444            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13445            pw.println();
13446            if (dumpAll) {
13447                pw.println("-------------------------------------------------------------------------------");
13448            }
13449            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13450            pw.println();
13451            if (dumpAll) {
13452                pw.println("-------------------------------------------------------------------------------");
13453            }
13454            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13455            pw.println();
13456            if (dumpAll) {
13457                pw.println("-------------------------------------------------------------------------------");
13458            }
13459            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13460            pw.println();
13461            if (dumpAll) {
13462                pw.println("-------------------------------------------------------------------------------");
13463            }
13464            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13465            pw.println();
13466            if (dumpAll) {
13467                pw.println("-------------------------------------------------------------------------------");
13468            }
13469            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13470            pw.println();
13471            if (dumpAll) {
13472                pw.println("-------------------------------------------------------------------------------");
13473            }
13474            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13475            if (mAssociations.size() > 0) {
13476                pw.println();
13477                if (dumpAll) {
13478                    pw.println("-------------------------------------------------------------------------------");
13479                }
13480                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13481            }
13482            pw.println();
13483            if (dumpAll) {
13484                pw.println("-------------------------------------------------------------------------------");
13485            }
13486            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13487        }
13488        Binder.restoreCallingIdentity(origId);
13489    }
13490
13491    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13492            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13493        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13494
13495        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13496                dumpPackage);
13497        boolean needSep = printedAnything;
13498
13499        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13500                dumpPackage, needSep, "  mFocusedActivity: ");
13501        if (printed) {
13502            printedAnything = true;
13503            needSep = false;
13504        }
13505
13506        if (dumpPackage == null) {
13507            if (needSep) {
13508                pw.println();
13509            }
13510            needSep = true;
13511            printedAnything = true;
13512            mStackSupervisor.dump(pw, "  ");
13513        }
13514
13515        if (!printedAnything) {
13516            pw.println("  (nothing)");
13517        }
13518    }
13519
13520    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13521            int opti, boolean dumpAll, String dumpPackage) {
13522        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13523
13524        boolean printedAnything = false;
13525
13526        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13527            boolean printedHeader = false;
13528
13529            final int N = mRecentTasks.size();
13530            for (int i=0; i<N; i++) {
13531                TaskRecord tr = mRecentTasks.get(i);
13532                if (dumpPackage != null) {
13533                    if (tr.realActivity == null ||
13534                            !dumpPackage.equals(tr.realActivity)) {
13535                        continue;
13536                    }
13537                }
13538                if (!printedHeader) {
13539                    pw.println("  Recent tasks:");
13540                    printedHeader = true;
13541                    printedAnything = true;
13542                }
13543                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13544                        pw.println(tr);
13545                if (dumpAll) {
13546                    mRecentTasks.get(i).dump(pw, "    ");
13547                }
13548            }
13549        }
13550
13551        if (!printedAnything) {
13552            pw.println("  (nothing)");
13553        }
13554    }
13555
13556    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13557            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13558        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13559
13560        int dumpUid = 0;
13561        if (dumpPackage != null) {
13562            IPackageManager pm = AppGlobals.getPackageManager();
13563            try {
13564                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13565            } catch (RemoteException e) {
13566            }
13567        }
13568
13569        boolean printedAnything = false;
13570
13571        final long now = SystemClock.uptimeMillis();
13572
13573        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13574            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13575                    = mAssociations.valueAt(i1);
13576            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13577                SparseArray<ArrayMap<String, Association>> sourceUids
13578                        = targetComponents.valueAt(i2);
13579                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13580                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13581                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13582                        Association ass = sourceProcesses.valueAt(i4);
13583                        if (dumpPackage != null) {
13584                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13585                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13586                                continue;
13587                            }
13588                        }
13589                        printedAnything = true;
13590                        pw.print("  ");
13591                        pw.print(ass.mTargetProcess);
13592                        pw.print("/");
13593                        UserHandle.formatUid(pw, ass.mTargetUid);
13594                        pw.print(" <- ");
13595                        pw.print(ass.mSourceProcess);
13596                        pw.print("/");
13597                        UserHandle.formatUid(pw, ass.mSourceUid);
13598                        pw.println();
13599                        pw.print("    via ");
13600                        pw.print(ass.mTargetComponent.flattenToShortString());
13601                        pw.println();
13602                        pw.print("    ");
13603                        long dur = ass.mTime;
13604                        if (ass.mNesting > 0) {
13605                            dur += now - ass.mStartTime;
13606                        }
13607                        TimeUtils.formatDuration(dur, pw);
13608                        pw.print(" (");
13609                        pw.print(ass.mCount);
13610                        pw.println(" times)");
13611                        if (ass.mNesting > 0) {
13612                            pw.print("    ");
13613                            pw.print(" Currently active: ");
13614                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13615                            pw.println();
13616                        }
13617                    }
13618                }
13619            }
13620
13621        }
13622
13623        if (!printedAnything) {
13624            pw.println("  (nothing)");
13625        }
13626    }
13627
13628    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13629            String header, boolean needSep) {
13630        boolean printed = false;
13631        int whichAppId = -1;
13632        if (dumpPackage != null) {
13633            try {
13634                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13635                        dumpPackage, 0);
13636                whichAppId = UserHandle.getAppId(info.uid);
13637            } catch (NameNotFoundException e) {
13638                e.printStackTrace();
13639            }
13640        }
13641        for (int i=0; i<uids.size(); i++) {
13642            UidRecord uidRec = uids.valueAt(i);
13643            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13644                continue;
13645            }
13646            if (!printed) {
13647                printed = true;
13648                if (needSep) {
13649                    pw.println();
13650                }
13651                pw.print("  ");
13652                pw.println(header);
13653                needSep = true;
13654            }
13655            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13656            pw.print(": "); pw.println(uidRec);
13657        }
13658        return printed;
13659    }
13660
13661    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13662            int opti, boolean dumpAll, String dumpPackage) {
13663        boolean needSep = false;
13664        boolean printedAnything = false;
13665        int numPers = 0;
13666
13667        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13668
13669        if (dumpAll) {
13670            final int NP = mProcessNames.getMap().size();
13671            for (int ip=0; ip<NP; ip++) {
13672                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13673                final int NA = procs.size();
13674                for (int ia=0; ia<NA; ia++) {
13675                    ProcessRecord r = procs.valueAt(ia);
13676                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13677                        continue;
13678                    }
13679                    if (!needSep) {
13680                        pw.println("  All known processes:");
13681                        needSep = true;
13682                        printedAnything = true;
13683                    }
13684                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13685                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13686                        pw.print(" "); pw.println(r);
13687                    r.dump(pw, "    ");
13688                    if (r.persistent) {
13689                        numPers++;
13690                    }
13691                }
13692            }
13693        }
13694
13695        if (mIsolatedProcesses.size() > 0) {
13696            boolean printed = false;
13697            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13698                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13699                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13700                    continue;
13701                }
13702                if (!printed) {
13703                    if (needSep) {
13704                        pw.println();
13705                    }
13706                    pw.println("  Isolated process list (sorted by uid):");
13707                    printedAnything = true;
13708                    printed = true;
13709                    needSep = true;
13710                }
13711                pw.println(String.format("%sIsolated #%2d: %s",
13712                        "    ", i, r.toString()));
13713            }
13714        }
13715
13716        if (mActiveUids.size() > 0) {
13717            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13718                printedAnything = needSep = true;
13719            }
13720        }
13721        if (mValidateUids.size() > 0) {
13722            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13723                printedAnything = needSep = true;
13724            }
13725        }
13726
13727        if (mLruProcesses.size() > 0) {
13728            if (needSep) {
13729                pw.println();
13730            }
13731            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13732                    pw.print(" total, non-act at ");
13733                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13734                    pw.print(", non-svc at ");
13735                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13736                    pw.println("):");
13737            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13738            needSep = true;
13739            printedAnything = true;
13740        }
13741
13742        if (dumpAll || dumpPackage != null) {
13743            synchronized (mPidsSelfLocked) {
13744                boolean printed = false;
13745                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13746                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13747                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13748                        continue;
13749                    }
13750                    if (!printed) {
13751                        if (needSep) pw.println();
13752                        needSep = true;
13753                        pw.println("  PID mappings:");
13754                        printed = true;
13755                        printedAnything = true;
13756                    }
13757                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13758                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13759                }
13760            }
13761        }
13762
13763        if (mForegroundProcesses.size() > 0) {
13764            synchronized (mPidsSelfLocked) {
13765                boolean printed = false;
13766                for (int i=0; i<mForegroundProcesses.size(); i++) {
13767                    ProcessRecord r = mPidsSelfLocked.get(
13768                            mForegroundProcesses.valueAt(i).pid);
13769                    if (dumpPackage != null && (r == null
13770                            || !r.pkgList.containsKey(dumpPackage))) {
13771                        continue;
13772                    }
13773                    if (!printed) {
13774                        if (needSep) pw.println();
13775                        needSep = true;
13776                        pw.println("  Foreground Processes:");
13777                        printed = true;
13778                        printedAnything = true;
13779                    }
13780                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13781                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13782                }
13783            }
13784        }
13785
13786        if (mPersistentStartingProcesses.size() > 0) {
13787            if (needSep) pw.println();
13788            needSep = true;
13789            printedAnything = true;
13790            pw.println("  Persisent processes that are starting:");
13791            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13792                    "Starting Norm", "Restarting PERS", dumpPackage);
13793        }
13794
13795        if (mRemovedProcesses.size() > 0) {
13796            if (needSep) pw.println();
13797            needSep = true;
13798            printedAnything = true;
13799            pw.println("  Processes that are being removed:");
13800            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13801                    "Removed Norm", "Removed PERS", dumpPackage);
13802        }
13803
13804        if (mProcessesOnHold.size() > 0) {
13805            if (needSep) pw.println();
13806            needSep = true;
13807            printedAnything = true;
13808            pw.println("  Processes that are on old until the system is ready:");
13809            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13810                    "OnHold Norm", "OnHold PERS", dumpPackage);
13811        }
13812
13813        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13814
13815        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
13816        if (needSep) {
13817            printedAnything = true;
13818        }
13819
13820        if (dumpPackage == null) {
13821            pw.println();
13822            needSep = false;
13823            mUserController.dump(pw, dumpAll);
13824        }
13825        if (mHomeProcess != null && (dumpPackage == null
13826                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13827            if (needSep) {
13828                pw.println();
13829                needSep = false;
13830            }
13831            pw.println("  mHomeProcess: " + mHomeProcess);
13832        }
13833        if (mPreviousProcess != null && (dumpPackage == null
13834                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13835            if (needSep) {
13836                pw.println();
13837                needSep = false;
13838            }
13839            pw.println("  mPreviousProcess: " + mPreviousProcess);
13840        }
13841        if (dumpAll) {
13842            StringBuilder sb = new StringBuilder(128);
13843            sb.append("  mPreviousProcessVisibleTime: ");
13844            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13845            pw.println(sb);
13846        }
13847        if (mHeavyWeightProcess != null && (dumpPackage == null
13848                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13849            if (needSep) {
13850                pw.println();
13851                needSep = false;
13852            }
13853            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13854        }
13855        if (dumpPackage == null) {
13856            pw.println("  mConfiguration: " + mConfiguration);
13857        }
13858        if (dumpAll) {
13859            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13860            if (mCompatModePackages.getPackages().size() > 0) {
13861                boolean printed = false;
13862                for (Map.Entry<String, Integer> entry
13863                        : mCompatModePackages.getPackages().entrySet()) {
13864                    String pkg = entry.getKey();
13865                    int mode = entry.getValue();
13866                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13867                        continue;
13868                    }
13869                    if (!printed) {
13870                        pw.println("  mScreenCompatPackages:");
13871                        printed = true;
13872                    }
13873                    pw.print("    "); pw.print(pkg); pw.print(": ");
13874                            pw.print(mode); pw.println();
13875                }
13876            }
13877        }
13878        if (dumpPackage == null) {
13879            pw.println("  mWakefulness="
13880                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13881            pw.println("  mSleepTokens=" + mSleepTokens);
13882            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13883                    + lockScreenShownToString());
13884            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13885            if (mRunningVoice != null) {
13886                pw.println("  mRunningVoice=" + mRunningVoice);
13887                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13888            }
13889        }
13890        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13891                || mOrigWaitForDebugger) {
13892            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13893                    || dumpPackage.equals(mOrigDebugApp)) {
13894                if (needSep) {
13895                    pw.println();
13896                    needSep = false;
13897                }
13898                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13899                        + " mDebugTransient=" + mDebugTransient
13900                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13901            }
13902        }
13903        if (mCurAppTimeTracker != null) {
13904            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13905        }
13906        if (mMemWatchProcesses.getMap().size() > 0) {
13907            pw.println("  Mem watch processes:");
13908            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13909                    = mMemWatchProcesses.getMap();
13910            for (int i=0; i<procs.size(); i++) {
13911                final String proc = procs.keyAt(i);
13912                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13913                for (int j=0; j<uids.size(); j++) {
13914                    if (needSep) {
13915                        pw.println();
13916                        needSep = false;
13917                    }
13918                    StringBuilder sb = new StringBuilder();
13919                    sb.append("    ").append(proc).append('/');
13920                    UserHandle.formatUid(sb, uids.keyAt(j));
13921                    Pair<Long, String> val = uids.valueAt(j);
13922                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13923                    if (val.second != null) {
13924                        sb.append(", report to ").append(val.second);
13925                    }
13926                    pw.println(sb.toString());
13927                }
13928            }
13929            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13930            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13931            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13932                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13933        }
13934        if (mTrackAllocationApp != null) {
13935            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13936                if (needSep) {
13937                    pw.println();
13938                    needSep = false;
13939                }
13940                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13941            }
13942        }
13943        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13944                || mProfileFd != null) {
13945            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13946                if (needSep) {
13947                    pw.println();
13948                    needSep = false;
13949                }
13950                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13951                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13952                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13953                        + mAutoStopProfiler);
13954                pw.println("  mProfileType=" + mProfileType);
13955            }
13956        }
13957        if (dumpPackage == null) {
13958            if (mAlwaysFinishActivities || mController != null) {
13959                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13960                        + " mController=" + mController);
13961            }
13962            if (dumpAll) {
13963                pw.println("  Total persistent processes: " + numPers);
13964                pw.println("  mProcessesReady=" + mProcessesReady
13965                        + " mSystemReady=" + mSystemReady
13966                        + " mBooted=" + mBooted
13967                        + " mFactoryTest=" + mFactoryTest);
13968                pw.println("  mBooting=" + mBooting
13969                        + " mCallFinishBooting=" + mCallFinishBooting
13970                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13971                pw.print("  mLastPowerCheckRealtime=");
13972                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13973                        pw.println("");
13974                pw.print("  mLastPowerCheckUptime=");
13975                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13976                        pw.println("");
13977                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13978                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13979                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13980                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13981                        + " (" + mLruProcesses.size() + " total)"
13982                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13983                        + " mNumServiceProcs=" + mNumServiceProcs
13984                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13985                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13986                        + " mLastMemoryLevel" + mLastMemoryLevel
13987                        + " mLastNumProcesses" + mLastNumProcesses);
13988                long now = SystemClock.uptimeMillis();
13989                pw.print("  mLastIdleTime=");
13990                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13991                        pw.print(" mLowRamSinceLastIdle=");
13992                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13993                        pw.println();
13994            }
13995        }
13996
13997        if (!printedAnything) {
13998            pw.println("  (nothing)");
13999        }
14000    }
14001
14002    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14003            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14004        if (mProcessesToGc.size() > 0) {
14005            boolean printed = false;
14006            long now = SystemClock.uptimeMillis();
14007            for (int i=0; i<mProcessesToGc.size(); i++) {
14008                ProcessRecord proc = mProcessesToGc.get(i);
14009                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14010                    continue;
14011                }
14012                if (!printed) {
14013                    if (needSep) pw.println();
14014                    needSep = true;
14015                    pw.println("  Processes that are waiting to GC:");
14016                    printed = true;
14017                }
14018                pw.print("    Process "); pw.println(proc);
14019                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14020                        pw.print(", last gced=");
14021                        pw.print(now-proc.lastRequestedGc);
14022                        pw.print(" ms ago, last lowMem=");
14023                        pw.print(now-proc.lastLowMemory);
14024                        pw.println(" ms ago");
14025
14026            }
14027        }
14028        return needSep;
14029    }
14030
14031    void printOomLevel(PrintWriter pw, String name, int adj) {
14032        pw.print("    ");
14033        if (adj >= 0) {
14034            pw.print(' ');
14035            if (adj < 10) pw.print(' ');
14036        } else {
14037            if (adj > -10) pw.print(' ');
14038        }
14039        pw.print(adj);
14040        pw.print(": ");
14041        pw.print(name);
14042        pw.print(" (");
14043        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14044        pw.println(")");
14045    }
14046
14047    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14048            int opti, boolean dumpAll) {
14049        boolean needSep = false;
14050
14051        if (mLruProcesses.size() > 0) {
14052            if (needSep) pw.println();
14053            needSep = true;
14054            pw.println("  OOM levels:");
14055            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14056            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14057            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14058            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14059            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14060            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14061            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14062            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14063            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14064            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14065            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14066            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14067            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14068            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14069
14070            if (needSep) pw.println();
14071            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14072                    pw.print(" total, non-act at ");
14073                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14074                    pw.print(", non-svc at ");
14075                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14076                    pw.println("):");
14077            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14078            needSep = true;
14079        }
14080
14081        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14082
14083        pw.println();
14084        pw.println("  mHomeProcess: " + mHomeProcess);
14085        pw.println("  mPreviousProcess: " + mPreviousProcess);
14086        if (mHeavyWeightProcess != null) {
14087            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14088        }
14089
14090        return true;
14091    }
14092
14093    /**
14094     * There are three ways to call this:
14095     *  - no provider specified: dump all the providers
14096     *  - a flattened component name that matched an existing provider was specified as the
14097     *    first arg: dump that one provider
14098     *  - the first arg isn't the flattened component name of an existing provider:
14099     *    dump all providers whose component contains the first arg as a substring
14100     */
14101    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14102            int opti, boolean dumpAll) {
14103        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14104    }
14105
14106    static class ItemMatcher {
14107        ArrayList<ComponentName> components;
14108        ArrayList<String> strings;
14109        ArrayList<Integer> objects;
14110        boolean all;
14111
14112        ItemMatcher() {
14113            all = true;
14114        }
14115
14116        void build(String name) {
14117            ComponentName componentName = ComponentName.unflattenFromString(name);
14118            if (componentName != null) {
14119                if (components == null) {
14120                    components = new ArrayList<ComponentName>();
14121                }
14122                components.add(componentName);
14123                all = false;
14124            } else {
14125                int objectId = 0;
14126                // Not a '/' separated full component name; maybe an object ID?
14127                try {
14128                    objectId = Integer.parseInt(name, 16);
14129                    if (objects == null) {
14130                        objects = new ArrayList<Integer>();
14131                    }
14132                    objects.add(objectId);
14133                    all = false;
14134                } catch (RuntimeException e) {
14135                    // Not an integer; just do string match.
14136                    if (strings == null) {
14137                        strings = new ArrayList<String>();
14138                    }
14139                    strings.add(name);
14140                    all = false;
14141                }
14142            }
14143        }
14144
14145        int build(String[] args, int opti) {
14146            for (; opti<args.length; opti++) {
14147                String name = args[opti];
14148                if ("--".equals(name)) {
14149                    return opti+1;
14150                }
14151                build(name);
14152            }
14153            return opti;
14154        }
14155
14156        boolean match(Object object, ComponentName comp) {
14157            if (all) {
14158                return true;
14159            }
14160            if (components != null) {
14161                for (int i=0; i<components.size(); i++) {
14162                    if (components.get(i).equals(comp)) {
14163                        return true;
14164                    }
14165                }
14166            }
14167            if (objects != null) {
14168                for (int i=0; i<objects.size(); i++) {
14169                    if (System.identityHashCode(object) == objects.get(i)) {
14170                        return true;
14171                    }
14172                }
14173            }
14174            if (strings != null) {
14175                String flat = comp.flattenToString();
14176                for (int i=0; i<strings.size(); i++) {
14177                    if (flat.contains(strings.get(i))) {
14178                        return true;
14179                    }
14180                }
14181            }
14182            return false;
14183        }
14184    }
14185
14186    /**
14187     * There are three things that cmd can be:
14188     *  - a flattened component name that matches an existing activity
14189     *  - the cmd arg isn't the flattened component name of an existing activity:
14190     *    dump all activity whose component contains the cmd as a substring
14191     *  - A hex number of the ActivityRecord object instance.
14192     */
14193    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14194            int opti, boolean dumpAll) {
14195        ArrayList<ActivityRecord> activities;
14196
14197        synchronized (this) {
14198            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14199        }
14200
14201        if (activities.size() <= 0) {
14202            return false;
14203        }
14204
14205        String[] newArgs = new String[args.length - opti];
14206        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14207
14208        TaskRecord lastTask = null;
14209        boolean needSep = false;
14210        for (int i=activities.size()-1; i>=0; i--) {
14211            ActivityRecord r = activities.get(i);
14212            if (needSep) {
14213                pw.println();
14214            }
14215            needSep = true;
14216            synchronized (this) {
14217                if (lastTask != r.task) {
14218                    lastTask = r.task;
14219                    pw.print("TASK "); pw.print(lastTask.affinity);
14220                            pw.print(" id="); pw.println(lastTask.taskId);
14221                    if (dumpAll) {
14222                        lastTask.dump(pw, "  ");
14223                    }
14224                }
14225            }
14226            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14227        }
14228        return true;
14229    }
14230
14231    /**
14232     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14233     * there is a thread associated with the activity.
14234     */
14235    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14236            final ActivityRecord r, String[] args, boolean dumpAll) {
14237        String innerPrefix = prefix + "  ";
14238        synchronized (this) {
14239            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14240                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14241                    pw.print(" pid=");
14242                    if (r.app != null) pw.println(r.app.pid);
14243                    else pw.println("(not running)");
14244            if (dumpAll) {
14245                r.dump(pw, innerPrefix);
14246            }
14247        }
14248        if (r.app != null && r.app.thread != null) {
14249            // flush anything that is already in the PrintWriter since the thread is going
14250            // to write to the file descriptor directly
14251            pw.flush();
14252            try {
14253                TransferPipe tp = new TransferPipe();
14254                try {
14255                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14256                            r.appToken, innerPrefix, args);
14257                    tp.go(fd);
14258                } finally {
14259                    tp.kill();
14260                }
14261            } catch (IOException e) {
14262                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14263            } catch (RemoteException e) {
14264                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14265            }
14266        }
14267    }
14268
14269    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14270            int opti, boolean dumpAll, String dumpPackage) {
14271        boolean needSep = false;
14272        boolean onlyHistory = false;
14273        boolean printedAnything = false;
14274
14275        if ("history".equals(dumpPackage)) {
14276            if (opti < args.length && "-s".equals(args[opti])) {
14277                dumpAll = false;
14278            }
14279            onlyHistory = true;
14280            dumpPackage = null;
14281        }
14282
14283        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14284        if (!onlyHistory && dumpAll) {
14285            if (mRegisteredReceivers.size() > 0) {
14286                boolean printed = false;
14287                Iterator it = mRegisteredReceivers.values().iterator();
14288                while (it.hasNext()) {
14289                    ReceiverList r = (ReceiverList)it.next();
14290                    if (dumpPackage != null && (r.app == null ||
14291                            !dumpPackage.equals(r.app.info.packageName))) {
14292                        continue;
14293                    }
14294                    if (!printed) {
14295                        pw.println("  Registered Receivers:");
14296                        needSep = true;
14297                        printed = true;
14298                        printedAnything = true;
14299                    }
14300                    pw.print("  * "); pw.println(r);
14301                    r.dump(pw, "    ");
14302                }
14303            }
14304
14305            if (mReceiverResolver.dump(pw, needSep ?
14306                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14307                    "    ", dumpPackage, false, false)) {
14308                needSep = true;
14309                printedAnything = true;
14310            }
14311        }
14312
14313        for (BroadcastQueue q : mBroadcastQueues) {
14314            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14315            printedAnything |= needSep;
14316        }
14317
14318        needSep = true;
14319
14320        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14321            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14322                if (needSep) {
14323                    pw.println();
14324                }
14325                needSep = true;
14326                printedAnything = true;
14327                pw.print("  Sticky broadcasts for user ");
14328                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14329                StringBuilder sb = new StringBuilder(128);
14330                for (Map.Entry<String, ArrayList<Intent>> ent
14331                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14332                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14333                    if (dumpAll) {
14334                        pw.println(":");
14335                        ArrayList<Intent> intents = ent.getValue();
14336                        final int N = intents.size();
14337                        for (int i=0; i<N; i++) {
14338                            sb.setLength(0);
14339                            sb.append("    Intent: ");
14340                            intents.get(i).toShortString(sb, false, true, false, false);
14341                            pw.println(sb.toString());
14342                            Bundle bundle = intents.get(i).getExtras();
14343                            if (bundle != null) {
14344                                pw.print("      ");
14345                                pw.println(bundle.toString());
14346                            }
14347                        }
14348                    } else {
14349                        pw.println("");
14350                    }
14351                }
14352            }
14353        }
14354
14355        if (!onlyHistory && dumpAll) {
14356            pw.println();
14357            for (BroadcastQueue queue : mBroadcastQueues) {
14358                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14359                        + queue.mBroadcastsScheduled);
14360            }
14361            pw.println("  mHandler:");
14362            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14363            needSep = true;
14364            printedAnything = true;
14365        }
14366
14367        if (!printedAnything) {
14368            pw.println("  (nothing)");
14369        }
14370    }
14371
14372    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14373            int opti, boolean dumpAll, String dumpPackage) {
14374        boolean needSep;
14375        boolean printedAnything = false;
14376
14377        ItemMatcher matcher = new ItemMatcher();
14378        matcher.build(args, opti);
14379
14380        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14381
14382        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14383        printedAnything |= needSep;
14384
14385        if (mLaunchingProviders.size() > 0) {
14386            boolean printed = false;
14387            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14388                ContentProviderRecord r = mLaunchingProviders.get(i);
14389                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14390                    continue;
14391                }
14392                if (!printed) {
14393                    if (needSep) pw.println();
14394                    needSep = true;
14395                    pw.println("  Launching content providers:");
14396                    printed = true;
14397                    printedAnything = true;
14398                }
14399                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14400                        pw.println(r);
14401            }
14402        }
14403
14404        if (!printedAnything) {
14405            pw.println("  (nothing)");
14406        }
14407    }
14408
14409    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14410            int opti, boolean dumpAll, String dumpPackage) {
14411        boolean needSep = false;
14412        boolean printedAnything = false;
14413
14414        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14415
14416        if (mGrantedUriPermissions.size() > 0) {
14417            boolean printed = false;
14418            int dumpUid = -2;
14419            if (dumpPackage != null) {
14420                try {
14421                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14422                            MATCH_UNINSTALLED_PACKAGES, 0);
14423                } catch (NameNotFoundException e) {
14424                    dumpUid = -1;
14425                }
14426            }
14427            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14428                int uid = mGrantedUriPermissions.keyAt(i);
14429                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14430                    continue;
14431                }
14432                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14433                if (!printed) {
14434                    if (needSep) pw.println();
14435                    needSep = true;
14436                    pw.println("  Granted Uri Permissions:");
14437                    printed = true;
14438                    printedAnything = true;
14439                }
14440                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14441                for (UriPermission perm : perms.values()) {
14442                    pw.print("    "); pw.println(perm);
14443                    if (dumpAll) {
14444                        perm.dump(pw, "      ");
14445                    }
14446                }
14447            }
14448        }
14449
14450        if (!printedAnything) {
14451            pw.println("  (nothing)");
14452        }
14453    }
14454
14455    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14456            int opti, boolean dumpAll, String dumpPackage) {
14457        boolean printed = false;
14458
14459        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14460
14461        if (mIntentSenderRecords.size() > 0) {
14462            Iterator<WeakReference<PendingIntentRecord>> it
14463                    = mIntentSenderRecords.values().iterator();
14464            while (it.hasNext()) {
14465                WeakReference<PendingIntentRecord> ref = it.next();
14466                PendingIntentRecord rec = ref != null ? ref.get(): null;
14467                if (dumpPackage != null && (rec == null
14468                        || !dumpPackage.equals(rec.key.packageName))) {
14469                    continue;
14470                }
14471                printed = true;
14472                if (rec != null) {
14473                    pw.print("  * "); pw.println(rec);
14474                    if (dumpAll) {
14475                        rec.dump(pw, "    ");
14476                    }
14477                } else {
14478                    pw.print("  * "); pw.println(ref);
14479                }
14480            }
14481        }
14482
14483        if (!printed) {
14484            pw.println("  (nothing)");
14485        }
14486    }
14487
14488    private static final int dumpProcessList(PrintWriter pw,
14489            ActivityManagerService service, List list,
14490            String prefix, String normalLabel, String persistentLabel,
14491            String dumpPackage) {
14492        int numPers = 0;
14493        final int N = list.size()-1;
14494        for (int i=N; i>=0; i--) {
14495            ProcessRecord r = (ProcessRecord)list.get(i);
14496            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14497                continue;
14498            }
14499            pw.println(String.format("%s%s #%2d: %s",
14500                    prefix, (r.persistent ? persistentLabel : normalLabel),
14501                    i, r.toString()));
14502            if (r.persistent) {
14503                numPers++;
14504            }
14505        }
14506        return numPers;
14507    }
14508
14509    private static final boolean dumpProcessOomList(PrintWriter pw,
14510            ActivityManagerService service, List<ProcessRecord> origList,
14511            String prefix, String normalLabel, String persistentLabel,
14512            boolean inclDetails, String dumpPackage) {
14513
14514        ArrayList<Pair<ProcessRecord, Integer>> list
14515                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14516        for (int i=0; i<origList.size(); i++) {
14517            ProcessRecord r = origList.get(i);
14518            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14519                continue;
14520            }
14521            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14522        }
14523
14524        if (list.size() <= 0) {
14525            return false;
14526        }
14527
14528        Comparator<Pair<ProcessRecord, Integer>> comparator
14529                = new Comparator<Pair<ProcessRecord, Integer>>() {
14530            @Override
14531            public int compare(Pair<ProcessRecord, Integer> object1,
14532                    Pair<ProcessRecord, Integer> object2) {
14533                if (object1.first.setAdj != object2.first.setAdj) {
14534                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14535                }
14536                if (object1.first.setProcState != object2.first.setProcState) {
14537                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14538                }
14539                if (object1.second.intValue() != object2.second.intValue()) {
14540                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14541                }
14542                return 0;
14543            }
14544        };
14545
14546        Collections.sort(list, comparator);
14547
14548        final long curRealtime = SystemClock.elapsedRealtime();
14549        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14550        final long curUptime = SystemClock.uptimeMillis();
14551        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14552
14553        for (int i=list.size()-1; i>=0; i--) {
14554            ProcessRecord r = list.get(i).first;
14555            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14556            char schedGroup;
14557            switch (r.setSchedGroup) {
14558                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14559                    schedGroup = 'B';
14560                    break;
14561                case Process.THREAD_GROUP_DEFAULT:
14562                    schedGroup = 'F';
14563                    break;
14564                default:
14565                    schedGroup = '?';
14566                    break;
14567            }
14568            char foreground;
14569            if (r.foregroundActivities) {
14570                foreground = 'A';
14571            } else if (r.foregroundServices) {
14572                foreground = 'S';
14573            } else {
14574                foreground = ' ';
14575            }
14576            String procState = ProcessList.makeProcStateString(r.curProcState);
14577            pw.print(prefix);
14578            pw.print(r.persistent ? persistentLabel : normalLabel);
14579            pw.print(" #");
14580            int num = (origList.size()-1)-list.get(i).second;
14581            if (num < 10) pw.print(' ');
14582            pw.print(num);
14583            pw.print(": ");
14584            pw.print(oomAdj);
14585            pw.print(' ');
14586            pw.print(schedGroup);
14587            pw.print('/');
14588            pw.print(foreground);
14589            pw.print('/');
14590            pw.print(procState);
14591            pw.print(" trm:");
14592            if (r.trimMemoryLevel < 10) pw.print(' ');
14593            pw.print(r.trimMemoryLevel);
14594            pw.print(' ');
14595            pw.print(r.toShortString());
14596            pw.print(" (");
14597            pw.print(r.adjType);
14598            pw.println(')');
14599            if (r.adjSource != null || r.adjTarget != null) {
14600                pw.print(prefix);
14601                pw.print("    ");
14602                if (r.adjTarget instanceof ComponentName) {
14603                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14604                } else if (r.adjTarget != null) {
14605                    pw.print(r.adjTarget.toString());
14606                } else {
14607                    pw.print("{null}");
14608                }
14609                pw.print("<=");
14610                if (r.adjSource instanceof ProcessRecord) {
14611                    pw.print("Proc{");
14612                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14613                    pw.println("}");
14614                } else if (r.adjSource != null) {
14615                    pw.println(r.adjSource.toString());
14616                } else {
14617                    pw.println("{null}");
14618                }
14619            }
14620            if (inclDetails) {
14621                pw.print(prefix);
14622                pw.print("    ");
14623                pw.print("oom: max="); pw.print(r.maxAdj);
14624                pw.print(" curRaw="); pw.print(r.curRawAdj);
14625                pw.print(" setRaw="); pw.print(r.setRawAdj);
14626                pw.print(" cur="); pw.print(r.curAdj);
14627                pw.print(" set="); pw.println(r.setAdj);
14628                pw.print(prefix);
14629                pw.print("    ");
14630                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14631                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14632                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14633                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14634                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14635                pw.println();
14636                pw.print(prefix);
14637                pw.print("    ");
14638                pw.print("cached="); pw.print(r.cached);
14639                pw.print(" empty="); pw.print(r.empty);
14640                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14641
14642                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14643                    if (r.lastWakeTime != 0) {
14644                        long wtime;
14645                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14646                        synchronized (stats) {
14647                            wtime = stats.getProcessWakeTime(r.info.uid,
14648                                    r.pid, curRealtime);
14649                        }
14650                        long timeUsed = wtime - r.lastWakeTime;
14651                        pw.print(prefix);
14652                        pw.print("    ");
14653                        pw.print("keep awake over ");
14654                        TimeUtils.formatDuration(realtimeSince, pw);
14655                        pw.print(" used ");
14656                        TimeUtils.formatDuration(timeUsed, pw);
14657                        pw.print(" (");
14658                        pw.print((timeUsed*100)/realtimeSince);
14659                        pw.println("%)");
14660                    }
14661                    if (r.lastCpuTime != 0) {
14662                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14663                        pw.print(prefix);
14664                        pw.print("    ");
14665                        pw.print("run cpu over ");
14666                        TimeUtils.formatDuration(uptimeSince, pw);
14667                        pw.print(" used ");
14668                        TimeUtils.formatDuration(timeUsed, pw);
14669                        pw.print(" (");
14670                        pw.print((timeUsed*100)/uptimeSince);
14671                        pw.println("%)");
14672                    }
14673                }
14674            }
14675        }
14676        return true;
14677    }
14678
14679    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14680            String[] args) {
14681        ArrayList<ProcessRecord> procs;
14682        synchronized (this) {
14683            if (args != null && args.length > start
14684                    && args[start].charAt(0) != '-') {
14685                procs = new ArrayList<ProcessRecord>();
14686                int pid = -1;
14687                try {
14688                    pid = Integer.parseInt(args[start]);
14689                } catch (NumberFormatException e) {
14690                }
14691                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14692                    ProcessRecord proc = mLruProcesses.get(i);
14693                    if (proc.pid == pid) {
14694                        procs.add(proc);
14695                    } else if (allPkgs && proc.pkgList != null
14696                            && proc.pkgList.containsKey(args[start])) {
14697                        procs.add(proc);
14698                    } else if (proc.processName.equals(args[start])) {
14699                        procs.add(proc);
14700                    }
14701                }
14702                if (procs.size() <= 0) {
14703                    return null;
14704                }
14705            } else {
14706                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14707            }
14708        }
14709        return procs;
14710    }
14711
14712    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14713            PrintWriter pw, String[] args) {
14714        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14715        if (procs == null) {
14716            pw.println("No process found for: " + args[0]);
14717            return;
14718        }
14719
14720        long uptime = SystemClock.uptimeMillis();
14721        long realtime = SystemClock.elapsedRealtime();
14722        pw.println("Applications Graphics Acceleration Info:");
14723        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14724
14725        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14726            ProcessRecord r = procs.get(i);
14727            if (r.thread != null) {
14728                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14729                pw.flush();
14730                try {
14731                    TransferPipe tp = new TransferPipe();
14732                    try {
14733                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14734                        tp.go(fd);
14735                    } finally {
14736                        tp.kill();
14737                    }
14738                } catch (IOException e) {
14739                    pw.println("Failure while dumping the app: " + r);
14740                    pw.flush();
14741                } catch (RemoteException e) {
14742                    pw.println("Got a RemoteException while dumping the app " + r);
14743                    pw.flush();
14744                }
14745            }
14746        }
14747    }
14748
14749    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14750        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14751        if (procs == null) {
14752            pw.println("No process found for: " + args[0]);
14753            return;
14754        }
14755
14756        pw.println("Applications Database Info:");
14757
14758        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14759            ProcessRecord r = procs.get(i);
14760            if (r.thread != null) {
14761                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14762                pw.flush();
14763                try {
14764                    TransferPipe tp = new TransferPipe();
14765                    try {
14766                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14767                        tp.go(fd);
14768                    } finally {
14769                        tp.kill();
14770                    }
14771                } catch (IOException e) {
14772                    pw.println("Failure while dumping the app: " + r);
14773                    pw.flush();
14774                } catch (RemoteException e) {
14775                    pw.println("Got a RemoteException while dumping the app " + r);
14776                    pw.flush();
14777                }
14778            }
14779        }
14780    }
14781
14782    final static class MemItem {
14783        final boolean isProc;
14784        final String label;
14785        final String shortLabel;
14786        final long pss;
14787        final long swapPss;
14788        final int id;
14789        final boolean hasActivities;
14790        ArrayList<MemItem> subitems;
14791
14792        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
14793                boolean _hasActivities) {
14794            isProc = true;
14795            label = _label;
14796            shortLabel = _shortLabel;
14797            pss = _pss;
14798            swapPss = _swapPss;
14799            id = _id;
14800            hasActivities = _hasActivities;
14801        }
14802
14803        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
14804            isProc = false;
14805            label = _label;
14806            shortLabel = _shortLabel;
14807            pss = _pss;
14808            swapPss = _swapPss;
14809            id = _id;
14810            hasActivities = false;
14811        }
14812    }
14813
14814    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14815            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
14816        if (sort && !isCompact) {
14817            Collections.sort(items, new Comparator<MemItem>() {
14818                @Override
14819                public int compare(MemItem lhs, MemItem rhs) {
14820                    if (lhs.pss < rhs.pss) {
14821                        return 1;
14822                    } else if (lhs.pss > rhs.pss) {
14823                        return -1;
14824                    }
14825                    return 0;
14826                }
14827            });
14828        }
14829
14830        for (int i=0; i<items.size(); i++) {
14831            MemItem mi = items.get(i);
14832            if (!isCompact) {
14833                if (dumpSwapPss) {
14834                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
14835                            mi.label, stringifyKBSize(mi.swapPss));
14836                } else {
14837                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
14838                }
14839            } else if (mi.isProc) {
14840                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14841                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
14842                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
14843                pw.println(mi.hasActivities ? ",a" : ",e");
14844            } else {
14845                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14846                pw.println(mi.pss); pw.print(dumpSwapPss ? mi.swapPss : "N/A");
14847            }
14848            if (mi.subitems != null) {
14849                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
14850                        true, isCompact, dumpSwapPss);
14851            }
14852        }
14853    }
14854
14855    // These are in KB.
14856    static final long[] DUMP_MEM_BUCKETS = new long[] {
14857        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14858        120*1024, 160*1024, 200*1024,
14859        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14860        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14861    };
14862
14863    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14864            boolean stackLike) {
14865        int start = label.lastIndexOf('.');
14866        if (start >= 0) start++;
14867        else start = 0;
14868        int end = label.length();
14869        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14870            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14871                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14872                out.append(bucket);
14873                out.append(stackLike ? "MB." : "MB ");
14874                out.append(label, start, end);
14875                return;
14876            }
14877        }
14878        out.append(memKB/1024);
14879        out.append(stackLike ? "MB." : "MB ");
14880        out.append(label, start, end);
14881    }
14882
14883    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14884            ProcessList.NATIVE_ADJ,
14885            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14886            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14887            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14888            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14889            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14890            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14891    };
14892    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14893            "Native",
14894            "System", "Persistent", "Persistent Service", "Foreground",
14895            "Visible", "Perceptible",
14896            "Heavy Weight", "Backup",
14897            "A Services", "Home",
14898            "Previous", "B Services", "Cached"
14899    };
14900    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14901            "native",
14902            "sys", "pers", "persvc", "fore",
14903            "vis", "percept",
14904            "heavy", "backup",
14905            "servicea", "home",
14906            "prev", "serviceb", "cached"
14907    };
14908
14909    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14910            long realtime, boolean isCheckinRequest, boolean isCompact) {
14911        if (isCheckinRequest || isCompact) {
14912            // short checkin version
14913            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14914        } else {
14915            pw.println("Applications Memory Usage (in Kilobytes):");
14916            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14917        }
14918    }
14919
14920    private static final int KSM_SHARED = 0;
14921    private static final int KSM_SHARING = 1;
14922    private static final int KSM_UNSHARED = 2;
14923    private static final int KSM_VOLATILE = 3;
14924
14925    private final long[] getKsmInfo() {
14926        long[] longOut = new long[4];
14927        final int[] SINGLE_LONG_FORMAT = new int[] {
14928            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14929        };
14930        long[] longTmp = new long[1];
14931        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14932                SINGLE_LONG_FORMAT, null, longTmp, null);
14933        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14934        longTmp[0] = 0;
14935        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14936                SINGLE_LONG_FORMAT, null, longTmp, null);
14937        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14938        longTmp[0] = 0;
14939        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14940                SINGLE_LONG_FORMAT, null, longTmp, null);
14941        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14942        longTmp[0] = 0;
14943        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14944                SINGLE_LONG_FORMAT, null, longTmp, null);
14945        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14946        return longOut;
14947    }
14948
14949    private static String stringifySize(long size, int order) {
14950        Locale locale = Locale.US;
14951        switch (order) {
14952            case 1:
14953                return String.format(locale, "%,13d", size);
14954            case 1024:
14955                return String.format(locale, "%,9dK", size / 1024);
14956            case 1024 * 1024:
14957                return String.format(locale, "%,5dM", size / 1024 / 1024);
14958            case 1024 * 1024 * 1024:
14959                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
14960            default:
14961                throw new IllegalArgumentException("Invalid size order");
14962        }
14963    }
14964
14965    private static String stringifyKBSize(long size) {
14966        return stringifySize(size * 1024, 1024);
14967    }
14968
14969    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14970            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14971        boolean dumpDetails = false;
14972        boolean dumpFullDetails = false;
14973        boolean dumpDalvik = false;
14974        boolean dumpSummaryOnly = false;
14975        boolean oomOnly = false;
14976        boolean isCompact = false;
14977        boolean localOnly = false;
14978        boolean packages = false;
14979        boolean isCheckinRequest = false;
14980        boolean dumpSwapPss = false;
14981
14982        int opti = 0;
14983        while (opti < args.length) {
14984            String opt = args[opti];
14985            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14986                break;
14987            }
14988            opti++;
14989            if ("-a".equals(opt)) {
14990                dumpDetails = true;
14991                dumpFullDetails = true;
14992                dumpDalvik = true;
14993                dumpSwapPss = true;
14994            } else if ("-d".equals(opt)) {
14995                dumpDalvik = true;
14996            } else if ("-c".equals(opt)) {
14997                isCompact = true;
14998            } else if ("-s".equals(opt)) {
14999                dumpDetails = true;
15000                dumpSummaryOnly = true;
15001            } else if ("-S".equals(opt)) {
15002                dumpSwapPss = true;
15003            } else if ("--oom".equals(opt)) {
15004                oomOnly = true;
15005            } else if ("--local".equals(opt)) {
15006                localOnly = true;
15007            } else if ("--package".equals(opt)) {
15008                packages = true;
15009            } else if ("--checkin".equals(opt)) {
15010                isCheckinRequest = true;
15011
15012            } else if ("-h".equals(opt)) {
15013                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15014                pw.println("  -a: include all available information for each process.");
15015                pw.println("  -d: include dalvik details.");
15016                pw.println("  -c: dump in a compact machine-parseable representation.");
15017                pw.println("  -s: dump only summary of application memory usage.");
15018                pw.println("  -S: dump also SwapPss.");
15019                pw.println("  --oom: only show processes organized by oom adj.");
15020                pw.println("  --local: only collect details locally, don't call process.");
15021                pw.println("  --package: interpret process arg as package, dumping all");
15022                pw.println("             processes that have loaded that package.");
15023                pw.println("  --checkin: dump data for a checkin");
15024                pw.println("If [process] is specified it can be the name or ");
15025                pw.println("pid of a specific process to dump.");
15026                return;
15027            } else {
15028                pw.println("Unknown argument: " + opt + "; use -h for help");
15029            }
15030        }
15031
15032        long uptime = SystemClock.uptimeMillis();
15033        long realtime = SystemClock.elapsedRealtime();
15034        final long[] tmpLong = new long[1];
15035
15036        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15037        if (procs == null) {
15038            // No Java processes.  Maybe they want to print a native process.
15039            if (args != null && args.length > opti
15040                    && args[opti].charAt(0) != '-') {
15041                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15042                        = new ArrayList<ProcessCpuTracker.Stats>();
15043                updateCpuStatsNow();
15044                int findPid = -1;
15045                try {
15046                    findPid = Integer.parseInt(args[opti]);
15047                } catch (NumberFormatException e) {
15048                }
15049                synchronized (mProcessCpuTracker) {
15050                    final int N = mProcessCpuTracker.countStats();
15051                    for (int i=0; i<N; i++) {
15052                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15053                        if (st.pid == findPid || (st.baseName != null
15054                                && st.baseName.equals(args[opti]))) {
15055                            nativeProcs.add(st);
15056                        }
15057                    }
15058                }
15059                if (nativeProcs.size() > 0) {
15060                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15061                            isCompact);
15062                    Debug.MemoryInfo mi = null;
15063                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15064                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15065                        final int pid = r.pid;
15066                        if (!isCheckinRequest && dumpDetails) {
15067                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15068                        }
15069                        if (mi == null) {
15070                            mi = new Debug.MemoryInfo();
15071                        }
15072                        if (dumpDetails || (!brief && !oomOnly)) {
15073                            Debug.getMemoryInfo(pid, mi);
15074                        } else {
15075                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15076                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15077                        }
15078                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15079                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15080                        if (isCheckinRequest) {
15081                            pw.println();
15082                        }
15083                    }
15084                    return;
15085                }
15086            }
15087            pw.println("No process found for: " + args[opti]);
15088            return;
15089        }
15090
15091        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15092            dumpDetails = true;
15093        }
15094
15095        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15096
15097        String[] innerArgs = new String[args.length-opti];
15098        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15099
15100        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15101        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15102        long nativePss = 0;
15103        long nativeSwapPss = 0;
15104        long dalvikPss = 0;
15105        long dalvikSwapPss = 0;
15106        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15107                EmptyArray.LONG;
15108        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15109                EmptyArray.LONG;
15110        long otherPss = 0;
15111        long otherSwapPss = 0;
15112        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15113        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15114
15115        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15116        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15117        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15118                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15119
15120        long totalPss = 0;
15121        long totalSwapPss = 0;
15122        long cachedPss = 0;
15123        long cachedSwapPss = 0;
15124        boolean hasSwapPss = false;
15125
15126        Debug.MemoryInfo mi = null;
15127        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15128            final ProcessRecord r = procs.get(i);
15129            final IApplicationThread thread;
15130            final int pid;
15131            final int oomAdj;
15132            final boolean hasActivities;
15133            synchronized (this) {
15134                thread = r.thread;
15135                pid = r.pid;
15136                oomAdj = r.getSetAdjWithServices();
15137                hasActivities = r.activities.size() > 0;
15138            }
15139            if (thread != null) {
15140                if (!isCheckinRequest && dumpDetails) {
15141                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15142                }
15143                if (mi == null) {
15144                    mi = new Debug.MemoryInfo();
15145                }
15146                if (dumpDetails || (!brief && !oomOnly)) {
15147                    Debug.getMemoryInfo(pid, mi);
15148                    hasSwapPss = mi.hasSwappedOutPss;
15149                } else {
15150                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15151                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15152                }
15153                if (dumpDetails) {
15154                    if (localOnly) {
15155                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15156                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15157                        if (isCheckinRequest) {
15158                            pw.println();
15159                        }
15160                    } else {
15161                        try {
15162                            pw.flush();
15163                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15164                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15165                        } catch (RemoteException e) {
15166                            if (!isCheckinRequest) {
15167                                pw.println("Got RemoteException!");
15168                                pw.flush();
15169                            }
15170                        }
15171                    }
15172                }
15173
15174                final long myTotalPss = mi.getTotalPss();
15175                final long myTotalUss = mi.getTotalUss();
15176                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15177
15178                synchronized (this) {
15179                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15180                        // Record this for posterity if the process has been stable.
15181                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15182                    }
15183                }
15184
15185                if (!isCheckinRequest && mi != null) {
15186                    totalPss += myTotalPss;
15187                    totalSwapPss += myTotalSwapPss;
15188                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15189                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15190                            myTotalSwapPss, pid, hasActivities);
15191                    procMems.add(pssItem);
15192                    procMemsMap.put(pid, pssItem);
15193
15194                    nativePss += mi.nativePss;
15195                    nativeSwapPss += mi.nativeSwappedOutPss;
15196                    dalvikPss += mi.dalvikPss;
15197                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15198                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15199                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15200                        dalvikSubitemSwapPss[j] +=
15201                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15202                    }
15203                    otherPss += mi.otherPss;
15204                    otherSwapPss += mi.otherSwappedOutPss;
15205                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15206                        long mem = mi.getOtherPss(j);
15207                        miscPss[j] += mem;
15208                        otherPss -= mem;
15209                        mem = mi.getOtherSwappedOutPss(j);
15210                        miscSwapPss[j] += mem;
15211                        otherSwapPss -= mem;
15212                    }
15213
15214                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15215                        cachedPss += myTotalPss;
15216                        cachedSwapPss += myTotalSwapPss;
15217                    }
15218
15219                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15220                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15221                                || oomIndex == (oomPss.length-1)) {
15222                            oomPss[oomIndex] += myTotalPss;
15223                            oomSwapPss[oomIndex] += myTotalSwapPss;
15224                            if (oomProcs[oomIndex] == null) {
15225                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15226                            }
15227                            oomProcs[oomIndex].add(pssItem);
15228                            break;
15229                        }
15230                    }
15231                }
15232            }
15233        }
15234
15235        long nativeProcTotalPss = 0;
15236
15237        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15238            // If we are showing aggregations, also look for native processes to
15239            // include so that our aggregations are more accurate.
15240            updateCpuStatsNow();
15241            mi = null;
15242            synchronized (mProcessCpuTracker) {
15243                final int N = mProcessCpuTracker.countStats();
15244                for (int i=0; i<N; i++) {
15245                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15246                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15247                        if (mi == null) {
15248                            mi = new Debug.MemoryInfo();
15249                        }
15250                        if (!brief && !oomOnly) {
15251                            Debug.getMemoryInfo(st.pid, mi);
15252                        } else {
15253                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15254                            mi.nativePrivateDirty = (int)tmpLong[0];
15255                        }
15256
15257                        final long myTotalPss = mi.getTotalPss();
15258                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15259                        totalPss += myTotalPss;
15260                        nativeProcTotalPss += myTotalPss;
15261
15262                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15263                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15264                        procMems.add(pssItem);
15265
15266                        nativePss += mi.nativePss;
15267                        nativeSwapPss += mi.nativeSwappedOutPss;
15268                        dalvikPss += mi.dalvikPss;
15269                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15270                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15271                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15272                            dalvikSubitemSwapPss[j] +=
15273                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15274                        }
15275                        otherPss += mi.otherPss;
15276                        otherSwapPss += mi.otherSwappedOutPss;
15277                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15278                            long mem = mi.getOtherPss(j);
15279                            miscPss[j] += mem;
15280                            otherPss -= mem;
15281                            mem = mi.getOtherSwappedOutPss(j);
15282                            miscSwapPss[j] += mem;
15283                            otherSwapPss -= mem;
15284                        }
15285                        oomPss[0] += myTotalPss;
15286                        oomSwapPss[0] += myTotalSwapPss;
15287                        if (oomProcs[0] == null) {
15288                            oomProcs[0] = new ArrayList<MemItem>();
15289                        }
15290                        oomProcs[0].add(pssItem);
15291                    }
15292                }
15293            }
15294
15295            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15296
15297            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15298            final MemItem dalvikItem =
15299                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15300            if (dalvikSubitemPss.length > 0) {
15301                dalvikItem.subitems = new ArrayList<MemItem>();
15302                for (int j=0; j<dalvikSubitemPss.length; j++) {
15303                    final String name = Debug.MemoryInfo.getOtherLabel(
15304                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15305                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15306                                    dalvikSubitemSwapPss[j], j));
15307                }
15308            }
15309            catMems.add(dalvikItem);
15310            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15311            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15312                String label = Debug.MemoryInfo.getOtherLabel(j);
15313                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15314            }
15315
15316            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15317            for (int j=0; j<oomPss.length; j++) {
15318                if (oomPss[j] != 0) {
15319                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15320                            : DUMP_MEM_OOM_LABEL[j];
15321                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15322                            DUMP_MEM_OOM_ADJ[j]);
15323                    item.subitems = oomProcs[j];
15324                    oomMems.add(item);
15325                }
15326            }
15327
15328            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15329            if (!brief && !oomOnly && !isCompact) {
15330                pw.println();
15331                pw.println("Total PSS by process:");
15332                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15333                pw.println();
15334            }
15335            if (!isCompact) {
15336                pw.println("Total PSS by OOM adjustment:");
15337            }
15338            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15339            if (!brief && !oomOnly) {
15340                PrintWriter out = categoryPw != null ? categoryPw : pw;
15341                if (!isCompact) {
15342                    out.println();
15343                    out.println("Total PSS by category:");
15344                }
15345                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15346            }
15347            if (!isCompact) {
15348                pw.println();
15349            }
15350            MemInfoReader memInfo = new MemInfoReader();
15351            memInfo.readMemInfo();
15352            if (nativeProcTotalPss > 0) {
15353                synchronized (this) {
15354                    final long cachedKb = memInfo.getCachedSizeKb();
15355                    final long freeKb = memInfo.getFreeSizeKb();
15356                    final long zramKb = memInfo.getZramTotalSizeKb();
15357                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15358                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15359                            kernelKb*1024, nativeProcTotalPss*1024);
15360                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15361                            nativeProcTotalPss);
15362                }
15363            }
15364            if (!brief) {
15365                if (!isCompact) {
15366                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15367                    pw.print(" (status ");
15368                    switch (mLastMemoryLevel) {
15369                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15370                            pw.println("normal)");
15371                            break;
15372                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15373                            pw.println("moderate)");
15374                            break;
15375                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15376                            pw.println("low)");
15377                            break;
15378                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15379                            pw.println("critical)");
15380                            break;
15381                        default:
15382                            pw.print(mLastMemoryLevel);
15383                            pw.println(")");
15384                            break;
15385                    }
15386                    pw.print(" Free RAM: ");
15387                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15388                            + memInfo.getFreeSizeKb()));
15389                    pw.print(" (");
15390                    pw.print(stringifyKBSize(cachedPss));
15391                    pw.print(" cached pss + ");
15392                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15393                    pw.print(" cached kernel + ");
15394                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15395                    pw.println(" free)");
15396                } else {
15397                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15398                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15399                            + memInfo.getFreeSizeKb()); pw.print(",");
15400                    pw.println(totalPss - cachedPss);
15401                }
15402            }
15403            long lostRAM = memInfo.getTotalSizeKb()
15404                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15405                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15406            if (!isCompact) {
15407                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15408                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15409                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15410                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15411                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15412            } else {
15413                pw.print("lostram,"); pw.println(lostRAM);
15414            }
15415            if (!brief) {
15416                if (memInfo.getZramTotalSizeKb() != 0) {
15417                    if (!isCompact) {
15418                        pw.print("     ZRAM: ");
15419                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15420                                pw.print(" physical used for ");
15421                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15422                                        - memInfo.getSwapFreeSizeKb()));
15423                                pw.print(" in swap (");
15424                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15425                                pw.println(" total swap)");
15426                    } else {
15427                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15428                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15429                                pw.println(memInfo.getSwapFreeSizeKb());
15430                    }
15431                }
15432                final long[] ksm = getKsmInfo();
15433                if (!isCompact) {
15434                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15435                            || ksm[KSM_VOLATILE] != 0) {
15436                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15437                                pw.print(" saved from shared ");
15438                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15439                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15440                                pw.print(" unshared; ");
15441                                pw.print(stringifyKBSize(
15442                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15443                    }
15444                    pw.print("   Tuning: ");
15445                    pw.print(ActivityManager.staticGetMemoryClass());
15446                    pw.print(" (large ");
15447                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15448                    pw.print("), oom ");
15449                    pw.print(stringifySize(
15450                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15451                    pw.print(", restore limit ");
15452                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15453                    if (ActivityManager.isLowRamDeviceStatic()) {
15454                        pw.print(" (low-ram)");
15455                    }
15456                    if (ActivityManager.isHighEndGfx()) {
15457                        pw.print(" (high-end-gfx)");
15458                    }
15459                    pw.println();
15460                } else {
15461                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15462                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15463                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15464                    pw.print("tuning,");
15465                    pw.print(ActivityManager.staticGetMemoryClass());
15466                    pw.print(',');
15467                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15468                    pw.print(',');
15469                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15470                    if (ActivityManager.isLowRamDeviceStatic()) {
15471                        pw.print(",low-ram");
15472                    }
15473                    if (ActivityManager.isHighEndGfx()) {
15474                        pw.print(",high-end-gfx");
15475                    }
15476                    pw.println();
15477                }
15478            }
15479        }
15480    }
15481
15482    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15483            long memtrack, String name) {
15484        sb.append("  ");
15485        sb.append(ProcessList.makeOomAdjString(oomAdj));
15486        sb.append(' ');
15487        sb.append(ProcessList.makeProcStateString(procState));
15488        sb.append(' ');
15489        ProcessList.appendRamKb(sb, pss);
15490        sb.append(": ");
15491        sb.append(name);
15492        if (memtrack > 0) {
15493            sb.append(" (");
15494            sb.append(stringifyKBSize(memtrack));
15495            sb.append(" memtrack)");
15496        }
15497    }
15498
15499    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15500        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15501        sb.append(" (pid ");
15502        sb.append(mi.pid);
15503        sb.append(") ");
15504        sb.append(mi.adjType);
15505        sb.append('\n');
15506        if (mi.adjReason != null) {
15507            sb.append("                      ");
15508            sb.append(mi.adjReason);
15509            sb.append('\n');
15510        }
15511    }
15512
15513    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15514        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15515        for (int i=0, N=memInfos.size(); i<N; i++) {
15516            ProcessMemInfo mi = memInfos.get(i);
15517            infoMap.put(mi.pid, mi);
15518        }
15519        updateCpuStatsNow();
15520        long[] memtrackTmp = new long[1];
15521        synchronized (mProcessCpuTracker) {
15522            final int N = mProcessCpuTracker.countStats();
15523            for (int i=0; i<N; i++) {
15524                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15525                if (st.vsize > 0) {
15526                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15527                    if (pss > 0) {
15528                        if (infoMap.indexOfKey(st.pid) < 0) {
15529                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15530                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15531                            mi.pss = pss;
15532                            mi.memtrack = memtrackTmp[0];
15533                            memInfos.add(mi);
15534                        }
15535                    }
15536                }
15537            }
15538        }
15539
15540        long totalPss = 0;
15541        long totalMemtrack = 0;
15542        for (int i=0, N=memInfos.size(); i<N; i++) {
15543            ProcessMemInfo mi = memInfos.get(i);
15544            if (mi.pss == 0) {
15545                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15546                mi.memtrack = memtrackTmp[0];
15547            }
15548            totalPss += mi.pss;
15549            totalMemtrack += mi.memtrack;
15550        }
15551        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15552            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15553                if (lhs.oomAdj != rhs.oomAdj) {
15554                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15555                }
15556                if (lhs.pss != rhs.pss) {
15557                    return lhs.pss < rhs.pss ? 1 : -1;
15558                }
15559                return 0;
15560            }
15561        });
15562
15563        StringBuilder tag = new StringBuilder(128);
15564        StringBuilder stack = new StringBuilder(128);
15565        tag.append("Low on memory -- ");
15566        appendMemBucket(tag, totalPss, "total", false);
15567        appendMemBucket(stack, totalPss, "total", true);
15568
15569        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15570        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15571        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15572
15573        boolean firstLine = true;
15574        int lastOomAdj = Integer.MIN_VALUE;
15575        long extraNativeRam = 0;
15576        long extraNativeMemtrack = 0;
15577        long cachedPss = 0;
15578        for (int i=0, N=memInfos.size(); i<N; i++) {
15579            ProcessMemInfo mi = memInfos.get(i);
15580
15581            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15582                cachedPss += mi.pss;
15583            }
15584
15585            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15586                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15587                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15588                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15589                if (lastOomAdj != mi.oomAdj) {
15590                    lastOomAdj = mi.oomAdj;
15591                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15592                        tag.append(" / ");
15593                    }
15594                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15595                        if (firstLine) {
15596                            stack.append(":");
15597                            firstLine = false;
15598                        }
15599                        stack.append("\n\t at ");
15600                    } else {
15601                        stack.append("$");
15602                    }
15603                } else {
15604                    tag.append(" ");
15605                    stack.append("$");
15606                }
15607                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15608                    appendMemBucket(tag, mi.pss, mi.name, false);
15609                }
15610                appendMemBucket(stack, mi.pss, mi.name, true);
15611                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15612                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15613                    stack.append("(");
15614                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15615                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15616                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15617                            stack.append(":");
15618                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15619                        }
15620                    }
15621                    stack.append(")");
15622                }
15623            }
15624
15625            appendMemInfo(fullNativeBuilder, mi);
15626            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15627                // The short form only has native processes that are >= 512K.
15628                if (mi.pss >= 512) {
15629                    appendMemInfo(shortNativeBuilder, mi);
15630                } else {
15631                    extraNativeRam += mi.pss;
15632                    extraNativeMemtrack += mi.memtrack;
15633                }
15634            } else {
15635                // Short form has all other details, but if we have collected RAM
15636                // from smaller native processes let's dump a summary of that.
15637                if (extraNativeRam > 0) {
15638                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15639                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15640                    shortNativeBuilder.append('\n');
15641                    extraNativeRam = 0;
15642                }
15643                appendMemInfo(fullJavaBuilder, mi);
15644            }
15645        }
15646
15647        fullJavaBuilder.append("           ");
15648        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15649        fullJavaBuilder.append(": TOTAL");
15650        if (totalMemtrack > 0) {
15651            fullJavaBuilder.append(" (");
15652            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15653            fullJavaBuilder.append(" memtrack)");
15654        } else {
15655        }
15656        fullJavaBuilder.append("\n");
15657
15658        MemInfoReader memInfo = new MemInfoReader();
15659        memInfo.readMemInfo();
15660        final long[] infos = memInfo.getRawInfo();
15661
15662        StringBuilder memInfoBuilder = new StringBuilder(1024);
15663        Debug.getMemInfo(infos);
15664        memInfoBuilder.append("  MemInfo: ");
15665        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15666        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15667        memInfoBuilder.append(stringifyKBSize(
15668                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15669        memInfoBuilder.append(stringifyKBSize(
15670                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15671        memInfoBuilder.append(stringifyKBSize(
15672                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15673        memInfoBuilder.append("           ");
15674        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15675        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15676        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15677        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15678        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15679            memInfoBuilder.append("  ZRAM: ");
15680            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15681            memInfoBuilder.append(" RAM, ");
15682            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15683            memInfoBuilder.append(" swap total, ");
15684            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15685            memInfoBuilder.append(" swap free\n");
15686        }
15687        final long[] ksm = getKsmInfo();
15688        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15689                || ksm[KSM_VOLATILE] != 0) {
15690            memInfoBuilder.append("  KSM: ");
15691            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15692            memInfoBuilder.append(" saved from shared ");
15693            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15694            memInfoBuilder.append("\n       ");
15695            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15696            memInfoBuilder.append(" unshared; ");
15697            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15698            memInfoBuilder.append(" volatile\n");
15699        }
15700        memInfoBuilder.append("  Free RAM: ");
15701        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15702                + memInfo.getFreeSizeKb()));
15703        memInfoBuilder.append("\n");
15704        memInfoBuilder.append("  Used RAM: ");
15705        memInfoBuilder.append(stringifyKBSize(
15706                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15707        memInfoBuilder.append("\n");
15708        memInfoBuilder.append("  Lost RAM: ");
15709        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15710                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15711                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15712        memInfoBuilder.append("\n");
15713        Slog.i(TAG, "Low on memory:");
15714        Slog.i(TAG, shortNativeBuilder.toString());
15715        Slog.i(TAG, fullJavaBuilder.toString());
15716        Slog.i(TAG, memInfoBuilder.toString());
15717
15718        StringBuilder dropBuilder = new StringBuilder(1024);
15719        /*
15720        StringWriter oomSw = new StringWriter();
15721        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15722        StringWriter catSw = new StringWriter();
15723        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15724        String[] emptyArgs = new String[] { };
15725        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15726        oomPw.flush();
15727        String oomString = oomSw.toString();
15728        */
15729        dropBuilder.append("Low on memory:");
15730        dropBuilder.append(stack);
15731        dropBuilder.append('\n');
15732        dropBuilder.append(fullNativeBuilder);
15733        dropBuilder.append(fullJavaBuilder);
15734        dropBuilder.append('\n');
15735        dropBuilder.append(memInfoBuilder);
15736        dropBuilder.append('\n');
15737        /*
15738        dropBuilder.append(oomString);
15739        dropBuilder.append('\n');
15740        */
15741        StringWriter catSw = new StringWriter();
15742        synchronized (ActivityManagerService.this) {
15743            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15744            String[] emptyArgs = new String[] { };
15745            catPw.println();
15746            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15747            catPw.println();
15748            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15749                    false, false, null);
15750            catPw.println();
15751            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15752            catPw.flush();
15753        }
15754        dropBuilder.append(catSw.toString());
15755        addErrorToDropBox("lowmem", null, "system_server", null,
15756                null, tag.toString(), dropBuilder.toString(), null, null);
15757        //Slog.i(TAG, "Sent to dropbox:");
15758        //Slog.i(TAG, dropBuilder.toString());
15759        synchronized (ActivityManagerService.this) {
15760            long now = SystemClock.uptimeMillis();
15761            if (mLastMemUsageReportTime < now) {
15762                mLastMemUsageReportTime = now;
15763            }
15764        }
15765    }
15766
15767    /**
15768     * Searches array of arguments for the specified string
15769     * @param args array of argument strings
15770     * @param value value to search for
15771     * @return true if the value is contained in the array
15772     */
15773    private static boolean scanArgs(String[] args, String value) {
15774        if (args != null) {
15775            for (String arg : args) {
15776                if (value.equals(arg)) {
15777                    return true;
15778                }
15779            }
15780        }
15781        return false;
15782    }
15783
15784    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15785            ContentProviderRecord cpr, boolean always) {
15786        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15787
15788        if (!inLaunching || always) {
15789            synchronized (cpr) {
15790                cpr.launchingApp = null;
15791                cpr.notifyAll();
15792            }
15793            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15794            String names[] = cpr.info.authority.split(";");
15795            for (int j = 0; j < names.length; j++) {
15796                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15797            }
15798        }
15799
15800        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15801            ContentProviderConnection conn = cpr.connections.get(i);
15802            if (conn.waiting) {
15803                // If this connection is waiting for the provider, then we don't
15804                // need to mess with its process unless we are always removing
15805                // or for some reason the provider is not currently launching.
15806                if (inLaunching && !always) {
15807                    continue;
15808                }
15809            }
15810            ProcessRecord capp = conn.client;
15811            conn.dead = true;
15812            if (conn.stableCount > 0) {
15813                if (!capp.persistent && capp.thread != null
15814                        && capp.pid != 0
15815                        && capp.pid != MY_PID) {
15816                    capp.kill("depends on provider "
15817                            + cpr.name.flattenToShortString()
15818                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15819                }
15820            } else if (capp.thread != null && conn.provider.provider != null) {
15821                try {
15822                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15823                } catch (RemoteException e) {
15824                }
15825                // In the protocol here, we don't expect the client to correctly
15826                // clean up this connection, we'll just remove it.
15827                cpr.connections.remove(i);
15828                if (conn.client.conProviders.remove(conn)) {
15829                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15830                }
15831            }
15832        }
15833
15834        if (inLaunching && always) {
15835            mLaunchingProviders.remove(cpr);
15836        }
15837        return inLaunching;
15838    }
15839
15840    /**
15841     * Main code for cleaning up a process when it has gone away.  This is
15842     * called both as a result of the process dying, or directly when stopping
15843     * a process when running in single process mode.
15844     *
15845     * @return Returns true if the given process has been restarted, so the
15846     * app that was passed in must remain on the process lists.
15847     */
15848    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15849            boolean restarting, boolean allowRestart, int index) {
15850        if (index >= 0) {
15851            removeLruProcessLocked(app);
15852            ProcessList.remove(app.pid);
15853        }
15854
15855        mProcessesToGc.remove(app);
15856        mPendingPssProcesses.remove(app);
15857
15858        // Dismiss any open dialogs.
15859        if (app.crashDialog != null && !app.forceCrashReport) {
15860            app.crashDialog.dismiss();
15861            app.crashDialog = null;
15862        }
15863        if (app.anrDialog != null) {
15864            app.anrDialog.dismiss();
15865            app.anrDialog = null;
15866        }
15867        if (app.waitDialog != null) {
15868            app.waitDialog.dismiss();
15869            app.waitDialog = null;
15870        }
15871
15872        app.crashing = false;
15873        app.notResponding = false;
15874
15875        app.resetPackageList(mProcessStats);
15876        app.unlinkDeathRecipient();
15877        app.makeInactive(mProcessStats);
15878        app.waitingToKill = null;
15879        app.forcingToForeground = null;
15880        updateProcessForegroundLocked(app, false, false);
15881        app.foregroundActivities = false;
15882        app.hasShownUi = false;
15883        app.treatLikeActivity = false;
15884        app.hasAboveClient = false;
15885        app.hasClientActivities = false;
15886
15887        mServices.killServicesLocked(app, allowRestart);
15888
15889        boolean restart = false;
15890
15891        // Remove published content providers.
15892        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15893            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15894            final boolean always = app.bad || !allowRestart;
15895            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15896            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15897                // We left the provider in the launching list, need to
15898                // restart it.
15899                restart = true;
15900            }
15901
15902            cpr.provider = null;
15903            cpr.proc = null;
15904        }
15905        app.pubProviders.clear();
15906
15907        // Take care of any launching providers waiting for this process.
15908        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15909            restart = true;
15910        }
15911
15912        // Unregister from connected content providers.
15913        if (!app.conProviders.isEmpty()) {
15914            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15915                ContentProviderConnection conn = app.conProviders.get(i);
15916                conn.provider.connections.remove(conn);
15917                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15918                        conn.provider.name);
15919            }
15920            app.conProviders.clear();
15921        }
15922
15923        // At this point there may be remaining entries in mLaunchingProviders
15924        // where we were the only one waiting, so they are no longer of use.
15925        // Look for these and clean up if found.
15926        // XXX Commented out for now.  Trying to figure out a way to reproduce
15927        // the actual situation to identify what is actually going on.
15928        if (false) {
15929            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15930                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15931                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15932                    synchronized (cpr) {
15933                        cpr.launchingApp = null;
15934                        cpr.notifyAll();
15935                    }
15936                }
15937            }
15938        }
15939
15940        skipCurrentReceiverLocked(app);
15941
15942        // Unregister any receivers.
15943        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15944            removeReceiverLocked(app.receivers.valueAt(i));
15945        }
15946        app.receivers.clear();
15947
15948        // If the app is undergoing backup, tell the backup manager about it
15949        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15950            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15951                    + mBackupTarget.appInfo + " died during backup");
15952            try {
15953                IBackupManager bm = IBackupManager.Stub.asInterface(
15954                        ServiceManager.getService(Context.BACKUP_SERVICE));
15955                bm.agentDisconnected(app.info.packageName);
15956            } catch (RemoteException e) {
15957                // can't happen; backup manager is local
15958            }
15959        }
15960
15961        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15962            ProcessChangeItem item = mPendingProcessChanges.get(i);
15963            if (item.pid == app.pid) {
15964                mPendingProcessChanges.remove(i);
15965                mAvailProcessChanges.add(item);
15966            }
15967        }
15968        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
15969                null).sendToTarget();
15970
15971        // If the caller is restarting this app, then leave it in its
15972        // current lists and let the caller take care of it.
15973        if (restarting) {
15974            return false;
15975        }
15976
15977        if (!app.persistent || app.isolated) {
15978            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15979                    "Removing non-persistent process during cleanup: " + app);
15980            removeProcessNameLocked(app.processName, app.uid);
15981            if (mHeavyWeightProcess == app) {
15982                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15983                        mHeavyWeightProcess.userId, 0));
15984                mHeavyWeightProcess = null;
15985            }
15986        } else if (!app.removed) {
15987            // This app is persistent, so we need to keep its record around.
15988            // If it is not already on the pending app list, add it there
15989            // and start a new process for it.
15990            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15991                mPersistentStartingProcesses.add(app);
15992                restart = true;
15993            }
15994        }
15995        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15996                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15997        mProcessesOnHold.remove(app);
15998
15999        if (app == mHomeProcess) {
16000            mHomeProcess = null;
16001        }
16002        if (app == mPreviousProcess) {
16003            mPreviousProcess = null;
16004        }
16005
16006        if (restart && !app.isolated) {
16007            // We have components that still need to be running in the
16008            // process, so re-launch it.
16009            if (index < 0) {
16010                ProcessList.remove(app.pid);
16011            }
16012            addProcessNameLocked(app);
16013            startProcessLocked(app, "restart", app.processName);
16014            return true;
16015        } else if (app.pid > 0 && app.pid != MY_PID) {
16016            // Goodbye!
16017            boolean removed;
16018            synchronized (mPidsSelfLocked) {
16019                mPidsSelfLocked.remove(app.pid);
16020                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16021            }
16022            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16023            if (app.isolated) {
16024                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16025            }
16026            app.setPid(0);
16027        }
16028        return false;
16029    }
16030
16031    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16032        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16033            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16034            if (cpr.launchingApp == app) {
16035                return true;
16036            }
16037        }
16038        return false;
16039    }
16040
16041    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16042        // Look through the content providers we are waiting to have launched,
16043        // and if any run in this process then either schedule a restart of
16044        // the process or kill the client waiting for it if this process has
16045        // gone bad.
16046        boolean restart = false;
16047        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16048            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16049            if (cpr.launchingApp == app) {
16050                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16051                    restart = true;
16052                } else {
16053                    removeDyingProviderLocked(app, cpr, true);
16054                }
16055            }
16056        }
16057        return restart;
16058    }
16059
16060    // =========================================================
16061    // SERVICES
16062    // =========================================================
16063
16064    @Override
16065    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16066            int flags) {
16067        enforceNotIsolatedCaller("getServices");
16068        synchronized (this) {
16069            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16070        }
16071    }
16072
16073    @Override
16074    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16075        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16076        synchronized (this) {
16077            return mServices.getRunningServiceControlPanelLocked(name);
16078        }
16079    }
16080
16081    @Override
16082    public ComponentName startService(IApplicationThread caller, Intent service,
16083            String resolvedType, String callingPackage, int userId)
16084            throws TransactionTooLargeException {
16085        enforceNotIsolatedCaller("startService");
16086        // Refuse possible leaked file descriptors
16087        if (service != null && service.hasFileDescriptors() == true) {
16088            throw new IllegalArgumentException("File descriptors passed in Intent");
16089        }
16090
16091        if (callingPackage == null) {
16092            throw new IllegalArgumentException("callingPackage cannot be null");
16093        }
16094
16095        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16096                "startService: " + service + " type=" + resolvedType);
16097        synchronized(this) {
16098            final int callingPid = Binder.getCallingPid();
16099            final int callingUid = Binder.getCallingUid();
16100            final long origId = Binder.clearCallingIdentity();
16101            ComponentName res = mServices.startServiceLocked(caller, service,
16102                    resolvedType, callingPid, callingUid, callingPackage, userId);
16103            Binder.restoreCallingIdentity(origId);
16104            return res;
16105        }
16106    }
16107
16108    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16109            String callingPackage, int userId)
16110            throws TransactionTooLargeException {
16111        synchronized(this) {
16112            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16113                    "startServiceInPackage: " + service + " type=" + resolvedType);
16114            final long origId = Binder.clearCallingIdentity();
16115            ComponentName res = mServices.startServiceLocked(null, service,
16116                    resolvedType, -1, uid, callingPackage, userId);
16117            Binder.restoreCallingIdentity(origId);
16118            return res;
16119        }
16120    }
16121
16122    @Override
16123    public int stopService(IApplicationThread caller, Intent service,
16124            String resolvedType, int userId) {
16125        enforceNotIsolatedCaller("stopService");
16126        // Refuse possible leaked file descriptors
16127        if (service != null && service.hasFileDescriptors() == true) {
16128            throw new IllegalArgumentException("File descriptors passed in Intent");
16129        }
16130
16131        synchronized(this) {
16132            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16133        }
16134    }
16135
16136    @Override
16137    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16138        enforceNotIsolatedCaller("peekService");
16139        // Refuse possible leaked file descriptors
16140        if (service != null && service.hasFileDescriptors() == true) {
16141            throw new IllegalArgumentException("File descriptors passed in Intent");
16142        }
16143
16144        if (callingPackage == null) {
16145            throw new IllegalArgumentException("callingPackage cannot be null");
16146        }
16147
16148        synchronized(this) {
16149            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16150        }
16151    }
16152
16153    @Override
16154    public boolean stopServiceToken(ComponentName className, IBinder token,
16155            int startId) {
16156        synchronized(this) {
16157            return mServices.stopServiceTokenLocked(className, token, startId);
16158        }
16159    }
16160
16161    @Override
16162    public void setServiceForeground(ComponentName className, IBinder token,
16163            int id, Notification notification, boolean removeNotification) {
16164        synchronized(this) {
16165            mServices.setServiceForegroundLocked(className, token, id, notification,
16166                    removeNotification);
16167        }
16168    }
16169
16170    @Override
16171    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16172            boolean requireFull, String name, String callerPackage) {
16173        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16174                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16175    }
16176
16177    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16178            String className, int flags) {
16179        boolean result = false;
16180        // For apps that don't have pre-defined UIDs, check for permission
16181        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16182            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16183                if (ActivityManager.checkUidPermission(
16184                        INTERACT_ACROSS_USERS,
16185                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16186                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16187                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16188                            + " requests FLAG_SINGLE_USER, but app does not hold "
16189                            + INTERACT_ACROSS_USERS;
16190                    Slog.w(TAG, msg);
16191                    throw new SecurityException(msg);
16192                }
16193                // Permission passed
16194                result = true;
16195            }
16196        } else if ("system".equals(componentProcessName)) {
16197            result = true;
16198        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16199            // Phone app and persistent apps are allowed to export singleuser providers.
16200            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16201                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16202        }
16203        if (DEBUG_MU) Slog.v(TAG_MU,
16204                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16205                + Integer.toHexString(flags) + ") = " + result);
16206        return result;
16207    }
16208
16209    /**
16210     * Checks to see if the caller is in the same app as the singleton
16211     * component, or the component is in a special app. It allows special apps
16212     * to export singleton components but prevents exporting singleton
16213     * components for regular apps.
16214     */
16215    boolean isValidSingletonCall(int callingUid, int componentUid) {
16216        int componentAppId = UserHandle.getAppId(componentUid);
16217        return UserHandle.isSameApp(callingUid, componentUid)
16218                || componentAppId == Process.SYSTEM_UID
16219                || componentAppId == Process.PHONE_UID
16220                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16221                        == PackageManager.PERMISSION_GRANTED;
16222    }
16223
16224    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16225            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16226            int userId) throws TransactionTooLargeException {
16227        enforceNotIsolatedCaller("bindService");
16228
16229        // Refuse possible leaked file descriptors
16230        if (service != null && service.hasFileDescriptors() == true) {
16231            throw new IllegalArgumentException("File descriptors passed in Intent");
16232        }
16233
16234        if (callingPackage == null) {
16235            throw new IllegalArgumentException("callingPackage cannot be null");
16236        }
16237
16238        synchronized(this) {
16239            return mServices.bindServiceLocked(caller, token, service,
16240                    resolvedType, connection, flags, callingPackage, userId);
16241        }
16242    }
16243
16244    public boolean unbindService(IServiceConnection connection) {
16245        synchronized (this) {
16246            return mServices.unbindServiceLocked(connection);
16247        }
16248    }
16249
16250    public void publishService(IBinder token, Intent intent, IBinder service) {
16251        // Refuse possible leaked file descriptors
16252        if (intent != null && intent.hasFileDescriptors() == true) {
16253            throw new IllegalArgumentException("File descriptors passed in Intent");
16254        }
16255
16256        synchronized(this) {
16257            if (!(token instanceof ServiceRecord)) {
16258                throw new IllegalArgumentException("Invalid service token");
16259            }
16260            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16261        }
16262    }
16263
16264    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16265        // Refuse possible leaked file descriptors
16266        if (intent != null && intent.hasFileDescriptors() == true) {
16267            throw new IllegalArgumentException("File descriptors passed in Intent");
16268        }
16269
16270        synchronized(this) {
16271            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16272        }
16273    }
16274
16275    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16276        synchronized(this) {
16277            if (!(token instanceof ServiceRecord)) {
16278                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16279                throw new IllegalArgumentException("Invalid service token");
16280            }
16281            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16282        }
16283    }
16284
16285    // =========================================================
16286    // BACKUP AND RESTORE
16287    // =========================================================
16288
16289    // Cause the target app to be launched if necessary and its backup agent
16290    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16291    // activity manager to announce its creation.
16292    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16293        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16294                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16295        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16296
16297        synchronized(this) {
16298            // !!! TODO: currently no check here that we're already bound
16299            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16300            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16301            synchronized (stats) {
16302                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16303            }
16304
16305            // Backup agent is now in use, its package can't be stopped.
16306            try {
16307                AppGlobals.getPackageManager().setPackageStoppedState(
16308                        app.packageName, false, UserHandle.getUserId(app.uid));
16309            } catch (RemoteException e) {
16310            } catch (IllegalArgumentException e) {
16311                Slog.w(TAG, "Failed trying to unstop package "
16312                        + app.packageName + ": " + e);
16313            }
16314
16315            BackupRecord r = new BackupRecord(ss, app, backupMode);
16316            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16317                    ? new ComponentName(app.packageName, app.backupAgentName)
16318                    : new ComponentName("android", "FullBackupAgent");
16319            // startProcessLocked() returns existing proc's record if it's already running
16320            ProcessRecord proc = startProcessLocked(app.processName, app,
16321                    false, 0, "backup", hostingName, false, false, false);
16322            if (proc == null) {
16323                Slog.e(TAG, "Unable to start backup agent process " + r);
16324                return false;
16325            }
16326
16327            r.app = proc;
16328            mBackupTarget = r;
16329            mBackupAppName = app.packageName;
16330
16331            // Try not to kill the process during backup
16332            updateOomAdjLocked(proc);
16333
16334            // If the process is already attached, schedule the creation of the backup agent now.
16335            // If it is not yet live, this will be done when it attaches to the framework.
16336            if (proc.thread != null) {
16337                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16338                try {
16339                    proc.thread.scheduleCreateBackupAgent(app,
16340                            compatibilityInfoForPackageLocked(app), backupMode);
16341                } catch (RemoteException e) {
16342                    // Will time out on the backup manager side
16343                }
16344            } else {
16345                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16346            }
16347            // Invariants: at this point, the target app process exists and the application
16348            // is either already running or in the process of coming up.  mBackupTarget and
16349            // mBackupAppName describe the app, so that when it binds back to the AM we
16350            // know that it's scheduled for a backup-agent operation.
16351        }
16352
16353        return true;
16354    }
16355
16356    @Override
16357    public void clearPendingBackup() {
16358        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16359        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16360
16361        synchronized (this) {
16362            mBackupTarget = null;
16363            mBackupAppName = null;
16364        }
16365    }
16366
16367    // A backup agent has just come up
16368    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16369        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16370                + " = " + agent);
16371
16372        synchronized(this) {
16373            if (!agentPackageName.equals(mBackupAppName)) {
16374                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16375                return;
16376            }
16377        }
16378
16379        long oldIdent = Binder.clearCallingIdentity();
16380        try {
16381            IBackupManager bm = IBackupManager.Stub.asInterface(
16382                    ServiceManager.getService(Context.BACKUP_SERVICE));
16383            bm.agentConnected(agentPackageName, agent);
16384        } catch (RemoteException e) {
16385            // can't happen; the backup manager service is local
16386        } catch (Exception e) {
16387            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16388            e.printStackTrace();
16389        } finally {
16390            Binder.restoreCallingIdentity(oldIdent);
16391        }
16392    }
16393
16394    // done with this agent
16395    public void unbindBackupAgent(ApplicationInfo appInfo) {
16396        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16397        if (appInfo == null) {
16398            Slog.w(TAG, "unbind backup agent for null app");
16399            return;
16400        }
16401
16402        synchronized(this) {
16403            try {
16404                if (mBackupAppName == null) {
16405                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16406                    return;
16407                }
16408
16409                if (!mBackupAppName.equals(appInfo.packageName)) {
16410                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16411                    return;
16412                }
16413
16414                // Not backing this app up any more; reset its OOM adjustment
16415                final ProcessRecord proc = mBackupTarget.app;
16416                updateOomAdjLocked(proc);
16417
16418                // If the app crashed during backup, 'thread' will be null here
16419                if (proc.thread != null) {
16420                    try {
16421                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16422                                compatibilityInfoForPackageLocked(appInfo));
16423                    } catch (Exception e) {
16424                        Slog.e(TAG, "Exception when unbinding backup agent:");
16425                        e.printStackTrace();
16426                    }
16427                }
16428            } finally {
16429                mBackupTarget = null;
16430                mBackupAppName = null;
16431            }
16432        }
16433    }
16434    // =========================================================
16435    // BROADCASTS
16436    // =========================================================
16437
16438    boolean isPendingBroadcastProcessLocked(int pid) {
16439        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16440                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16441    }
16442
16443    void skipPendingBroadcastLocked(int pid) {
16444            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16445            for (BroadcastQueue queue : mBroadcastQueues) {
16446                queue.skipPendingBroadcastLocked(pid);
16447            }
16448    }
16449
16450    // The app just attached; send any pending broadcasts that it should receive
16451    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16452        boolean didSomething = false;
16453        for (BroadcastQueue queue : mBroadcastQueues) {
16454            didSomething |= queue.sendPendingBroadcastsLocked(app);
16455        }
16456        return didSomething;
16457    }
16458
16459    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16460            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16461        enforceNotIsolatedCaller("registerReceiver");
16462        ArrayList<Intent> stickyIntents = null;
16463        ProcessRecord callerApp = null;
16464        int callingUid;
16465        int callingPid;
16466        synchronized(this) {
16467            if (caller != null) {
16468                callerApp = getRecordForAppLocked(caller);
16469                if (callerApp == null) {
16470                    throw new SecurityException(
16471                            "Unable to find app for caller " + caller
16472                            + " (pid=" + Binder.getCallingPid()
16473                            + ") when registering receiver " + receiver);
16474                }
16475                if (callerApp.info.uid != Process.SYSTEM_UID &&
16476                        !callerApp.pkgList.containsKey(callerPackage) &&
16477                        !"android".equals(callerPackage)) {
16478                    throw new SecurityException("Given caller package " + callerPackage
16479                            + " is not running in process " + callerApp);
16480                }
16481                callingUid = callerApp.info.uid;
16482                callingPid = callerApp.pid;
16483            } else {
16484                callerPackage = null;
16485                callingUid = Binder.getCallingUid();
16486                callingPid = Binder.getCallingPid();
16487            }
16488
16489            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16490                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16491
16492            Iterator<String> actions = filter.actionsIterator();
16493            if (actions == null) {
16494                ArrayList<String> noAction = new ArrayList<String>(1);
16495                noAction.add(null);
16496                actions = noAction.iterator();
16497            }
16498
16499            // Collect stickies of users
16500            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16501            while (actions.hasNext()) {
16502                String action = actions.next();
16503                for (int id : userIds) {
16504                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16505                    if (stickies != null) {
16506                        ArrayList<Intent> intents = stickies.get(action);
16507                        if (intents != null) {
16508                            if (stickyIntents == null) {
16509                                stickyIntents = new ArrayList<Intent>();
16510                            }
16511                            stickyIntents.addAll(intents);
16512                        }
16513                    }
16514                }
16515            }
16516        }
16517
16518        ArrayList<Intent> allSticky = null;
16519        if (stickyIntents != null) {
16520            final ContentResolver resolver = mContext.getContentResolver();
16521            // Look for any matching sticky broadcasts...
16522            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16523                Intent intent = stickyIntents.get(i);
16524                // If intent has scheme "content", it will need to acccess
16525                // provider that needs to lock mProviderMap in ActivityThread
16526                // and also it may need to wait application response, so we
16527                // cannot lock ActivityManagerService here.
16528                if (filter.match(resolver, intent, true, TAG) >= 0) {
16529                    if (allSticky == null) {
16530                        allSticky = new ArrayList<Intent>();
16531                    }
16532                    allSticky.add(intent);
16533                }
16534            }
16535        }
16536
16537        // The first sticky in the list is returned directly back to the client.
16538        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16539        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16540        if (receiver == null) {
16541            return sticky;
16542        }
16543
16544        synchronized (this) {
16545            if (callerApp != null && (callerApp.thread == null
16546                    || callerApp.thread.asBinder() != caller.asBinder())) {
16547                // Original caller already died
16548                return null;
16549            }
16550            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16551            if (rl == null) {
16552                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16553                        userId, receiver);
16554                if (rl.app != null) {
16555                    rl.app.receivers.add(rl);
16556                } else {
16557                    try {
16558                        receiver.asBinder().linkToDeath(rl, 0);
16559                    } catch (RemoteException e) {
16560                        return sticky;
16561                    }
16562                    rl.linkedToDeath = true;
16563                }
16564                mRegisteredReceivers.put(receiver.asBinder(), rl);
16565            } else if (rl.uid != callingUid) {
16566                throw new IllegalArgumentException(
16567                        "Receiver requested to register for uid " + callingUid
16568                        + " was previously registered for uid " + rl.uid);
16569            } else if (rl.pid != callingPid) {
16570                throw new IllegalArgumentException(
16571                        "Receiver requested to register for pid " + callingPid
16572                        + " was previously registered for pid " + rl.pid);
16573            } else if (rl.userId != userId) {
16574                throw new IllegalArgumentException(
16575                        "Receiver requested to register for user " + userId
16576                        + " was previously registered for user " + rl.userId);
16577            }
16578            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16579                    permission, callingUid, userId);
16580            rl.add(bf);
16581            if (!bf.debugCheck()) {
16582                Slog.w(TAG, "==> For Dynamic broadcast");
16583            }
16584            mReceiverResolver.addFilter(bf);
16585
16586            // Enqueue broadcasts for all existing stickies that match
16587            // this filter.
16588            if (allSticky != null) {
16589                ArrayList receivers = new ArrayList();
16590                receivers.add(bf);
16591
16592                final int stickyCount = allSticky.size();
16593                for (int i = 0; i < stickyCount; i++) {
16594                    Intent intent = allSticky.get(i);
16595                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16596                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16597                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16598                            null, 0, null, null, false, true, true, -1);
16599                    queue.enqueueParallelBroadcastLocked(r);
16600                    queue.scheduleBroadcastsLocked();
16601                }
16602            }
16603
16604            return sticky;
16605        }
16606    }
16607
16608    public void unregisterReceiver(IIntentReceiver receiver) {
16609        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16610
16611        final long origId = Binder.clearCallingIdentity();
16612        try {
16613            boolean doTrim = false;
16614
16615            synchronized(this) {
16616                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16617                if (rl != null) {
16618                    final BroadcastRecord r = rl.curBroadcast;
16619                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16620                        final boolean doNext = r.queue.finishReceiverLocked(
16621                                r, r.resultCode, r.resultData, r.resultExtras,
16622                                r.resultAbort, false);
16623                        if (doNext) {
16624                            doTrim = true;
16625                            r.queue.processNextBroadcast(false);
16626                        }
16627                    }
16628
16629                    if (rl.app != null) {
16630                        rl.app.receivers.remove(rl);
16631                    }
16632                    removeReceiverLocked(rl);
16633                    if (rl.linkedToDeath) {
16634                        rl.linkedToDeath = false;
16635                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16636                    }
16637                }
16638            }
16639
16640            // If we actually concluded any broadcasts, we might now be able
16641            // to trim the recipients' apps from our working set
16642            if (doTrim) {
16643                trimApplications();
16644                return;
16645            }
16646
16647        } finally {
16648            Binder.restoreCallingIdentity(origId);
16649        }
16650    }
16651
16652    void removeReceiverLocked(ReceiverList rl) {
16653        mRegisteredReceivers.remove(rl.receiver.asBinder());
16654        for (int i = rl.size() - 1; i >= 0; i--) {
16655            mReceiverResolver.removeFilter(rl.get(i));
16656        }
16657    }
16658
16659    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16660        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16661            ProcessRecord r = mLruProcesses.get(i);
16662            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16663                try {
16664                    r.thread.dispatchPackageBroadcast(cmd, packages);
16665                } catch (RemoteException ex) {
16666                }
16667            }
16668        }
16669    }
16670
16671    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16672            int callingUid, int[] users) {
16673        // TODO: come back and remove this assumption to triage all broadcasts
16674        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16675
16676        List<ResolveInfo> receivers = null;
16677        try {
16678            HashSet<ComponentName> singleUserReceivers = null;
16679            boolean scannedFirstReceivers = false;
16680            for (int user : users) {
16681                // Skip users that have Shell restrictions
16682                if (callingUid == Process.SHELL_UID
16683                        && mUserController.hasUserRestriction(
16684                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16685                    continue;
16686                }
16687                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16688                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
16689                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16690                    // If this is not the system user, we need to check for
16691                    // any receivers that should be filtered out.
16692                    for (int i=0; i<newReceivers.size(); i++) {
16693                        ResolveInfo ri = newReceivers.get(i);
16694                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16695                            newReceivers.remove(i);
16696                            i--;
16697                        }
16698                    }
16699                }
16700                if (newReceivers != null && newReceivers.size() == 0) {
16701                    newReceivers = null;
16702                }
16703                if (receivers == null) {
16704                    receivers = newReceivers;
16705                } else if (newReceivers != null) {
16706                    // We need to concatenate the additional receivers
16707                    // found with what we have do far.  This would be easy,
16708                    // but we also need to de-dup any receivers that are
16709                    // singleUser.
16710                    if (!scannedFirstReceivers) {
16711                        // Collect any single user receivers we had already retrieved.
16712                        scannedFirstReceivers = true;
16713                        for (int i=0; i<receivers.size(); i++) {
16714                            ResolveInfo ri = receivers.get(i);
16715                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16716                                ComponentName cn = new ComponentName(
16717                                        ri.activityInfo.packageName, ri.activityInfo.name);
16718                                if (singleUserReceivers == null) {
16719                                    singleUserReceivers = new HashSet<ComponentName>();
16720                                }
16721                                singleUserReceivers.add(cn);
16722                            }
16723                        }
16724                    }
16725                    // Add the new results to the existing results, tracking
16726                    // and de-dupping single user receivers.
16727                    for (int i=0; i<newReceivers.size(); i++) {
16728                        ResolveInfo ri = newReceivers.get(i);
16729                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16730                            ComponentName cn = new ComponentName(
16731                                    ri.activityInfo.packageName, ri.activityInfo.name);
16732                            if (singleUserReceivers == null) {
16733                                singleUserReceivers = new HashSet<ComponentName>();
16734                            }
16735                            if (!singleUserReceivers.contains(cn)) {
16736                                singleUserReceivers.add(cn);
16737                                receivers.add(ri);
16738                            }
16739                        } else {
16740                            receivers.add(ri);
16741                        }
16742                    }
16743                }
16744            }
16745        } catch (RemoteException ex) {
16746            // pm is in same process, this will never happen.
16747        }
16748        return receivers;
16749    }
16750
16751    final int broadcastIntentLocked(ProcessRecord callerApp,
16752            String callerPackage, Intent intent, String resolvedType,
16753            IIntentReceiver resultTo, int resultCode, String resultData,
16754            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16755            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16756        intent = new Intent(intent);
16757
16758        // By default broadcasts do not go to stopped apps.
16759        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16760
16761        // If we have not finished booting, don't allow this to launch new processes.
16762        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16763            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16764        }
16765
16766        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16767                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16768                + " ordered=" + ordered + " userid=" + userId);
16769        if ((resultTo != null) && !ordered) {
16770            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16771        }
16772
16773        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16774                ALLOW_NON_FULL, "broadcast", callerPackage);
16775
16776        // Make sure that the user who is receiving this broadcast is running.
16777        // If not, we will just skip it. Make an exception for shutdown broadcasts
16778        // and upgrade steps.
16779
16780        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16781            if ((callingUid != Process.SYSTEM_UID
16782                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16783                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16784                Slog.w(TAG, "Skipping broadcast of " + intent
16785                        + ": user " + userId + " is stopped");
16786                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16787            }
16788        }
16789
16790        BroadcastOptions brOptions = null;
16791        if (bOptions != null) {
16792            brOptions = new BroadcastOptions(bOptions);
16793            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16794                // See if the caller is allowed to do this.  Note we are checking against
16795                // the actual real caller (not whoever provided the operation as say a
16796                // PendingIntent), because that who is actually supplied the arguments.
16797                if (checkComponentPermission(
16798                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16799                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16800                        != PackageManager.PERMISSION_GRANTED) {
16801                    String msg = "Permission Denial: " + intent.getAction()
16802                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16803                            + ", uid=" + callingUid + ")"
16804                            + " requires "
16805                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16806                    Slog.w(TAG, msg);
16807                    throw new SecurityException(msg);
16808                }
16809            }
16810        }
16811
16812        // Verify that protected broadcasts are only being sent by system code,
16813        // and that system code is only sending protected broadcasts.
16814        final String action = intent.getAction();
16815        final boolean isProtectedBroadcast;
16816        try {
16817            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
16818        } catch (RemoteException e) {
16819            Slog.w(TAG, "Remote exception", e);
16820            return ActivityManager.BROADCAST_SUCCESS;
16821        }
16822
16823        final boolean isCallerSystem;
16824        switch (UserHandle.getAppId(callingUid)) {
16825            case Process.ROOT_UID:
16826            case Process.SYSTEM_UID:
16827            case Process.PHONE_UID:
16828            case Process.SHELL_UID:
16829            case Process.BLUETOOTH_UID:
16830            case Process.NFC_UID:
16831                isCallerSystem = true;
16832                break;
16833            default:
16834                isCallerSystem = (callerApp != null) && callerApp.persistent;
16835                break;
16836        }
16837
16838        if (isCallerSystem) {
16839            if (isProtectedBroadcast
16840                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
16841                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
16842                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
16843                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
16844                // Broadcast is either protected, or it's a public action that
16845                // we've relaxed, so it's fine for system internals to send.
16846            } else {
16847                // The vast majority of broadcasts sent from system internals
16848                // should be protected to avoid security holes, so yell loudly
16849                // to ensure we examine these cases.
16850                Log.wtf(TAG, "Sending non-protected broadcast " + action
16851                        + " from system", new Throwable());
16852            }
16853
16854        } else {
16855            if (isProtectedBroadcast) {
16856                String msg = "Permission Denial: not allowed to send broadcast "
16857                        + action + " from pid="
16858                        + callingPid + ", uid=" + callingUid;
16859                Slog.w(TAG, msg);
16860                throw new SecurityException(msg);
16861
16862            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
16863                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
16864                // Special case for compatibility: we don't want apps to send this,
16865                // but historically it has not been protected and apps may be using it
16866                // to poke their own app widget.  So, instead of making it protected,
16867                // just limit it to the caller.
16868                if (callerApp == null) {
16869                    String msg = "Permission Denial: not allowed to send broadcast "
16870                            + action + " from unknown caller.";
16871                    Slog.w(TAG, msg);
16872                    throw new SecurityException(msg);
16873                } else if (intent.getComponent() != null) {
16874                    // They are good enough to send to an explicit component...  verify
16875                    // it is being sent to the calling app.
16876                    if (!intent.getComponent().getPackageName().equals(
16877                            callerApp.info.packageName)) {
16878                        String msg = "Permission Denial: not allowed to send broadcast "
16879                                + action + " to "
16880                                + intent.getComponent().getPackageName() + " from "
16881                                + callerApp.info.packageName;
16882                        Slog.w(TAG, msg);
16883                        throw new SecurityException(msg);
16884                    }
16885                } else {
16886                    // Limit broadcast to their own package.
16887                    intent.setPackage(callerApp.info.packageName);
16888                }
16889            }
16890        }
16891
16892        if (action != null) {
16893            switch (action) {
16894                case Intent.ACTION_UID_REMOVED:
16895                case Intent.ACTION_PACKAGE_REMOVED:
16896                case Intent.ACTION_PACKAGE_CHANGED:
16897                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16898                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16899                case Intent.ACTION_PACKAGES_SUSPENDED:
16900                case Intent.ACTION_PACKAGES_UNSUSPENDED:
16901                    // Handle special intents: if this broadcast is from the package
16902                    // manager about a package being removed, we need to remove all of
16903                    // its activities from the history stack.
16904                    if (checkComponentPermission(
16905                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16906                            callingPid, callingUid, -1, true)
16907                            != PackageManager.PERMISSION_GRANTED) {
16908                        String msg = "Permission Denial: " + intent.getAction()
16909                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16910                                + ", uid=" + callingUid + ")"
16911                                + " requires "
16912                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16913                        Slog.w(TAG, msg);
16914                        throw new SecurityException(msg);
16915                    }
16916                    switch (action) {
16917                        case Intent.ACTION_UID_REMOVED:
16918                            final Bundle intentExtras = intent.getExtras();
16919                            final int uid = intentExtras != null
16920                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16921                            if (uid >= 0) {
16922                                mBatteryStatsService.removeUid(uid);
16923                                mAppOpsService.uidRemoved(uid);
16924                            }
16925                            break;
16926                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16927                            // If resources are unavailable just force stop all those packages
16928                            // and flush the attribute cache as well.
16929                            String list[] =
16930                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16931                            if (list != null && list.length > 0) {
16932                                for (int i = 0; i < list.length; i++) {
16933                                    forceStopPackageLocked(list[i], -1, false, true, true,
16934                                            false, false, userId, "storage unmount");
16935                                }
16936                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16937                                sendPackageBroadcastLocked(
16938                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16939                                        userId);
16940                            }
16941                            break;
16942                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16943                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16944                            break;
16945                        case Intent.ACTION_PACKAGE_REMOVED:
16946                        case Intent.ACTION_PACKAGE_CHANGED:
16947                            Uri data = intent.getData();
16948                            String ssp;
16949                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16950                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16951                                boolean fullUninstall = removed &&
16952                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16953                                final boolean killProcess =
16954                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16955                                if (killProcess) {
16956                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16957                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16958                                            false, true, true, false, fullUninstall, userId,
16959                                            removed ? "pkg removed" : "pkg changed");
16960                                }
16961                                if (removed) {
16962                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16963                                            new String[] {ssp}, userId);
16964                                    if (fullUninstall) {
16965                                        mAppOpsService.packageRemoved(
16966                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16967
16968                                        // Remove all permissions granted from/to this package
16969                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16970
16971                                        removeTasksByPackageNameLocked(ssp, userId);
16972                                        mBatteryStatsService.notePackageUninstalled(ssp);
16973                                    }
16974                                } else {
16975                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16976                                            intent.getStringArrayExtra(
16977                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16978                                }
16979                            }
16980                            break;
16981                        case Intent.ACTION_PACKAGES_SUSPENDED:
16982                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
16983                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
16984                                    intent.getAction());
16985                            final String[] packageNames = intent.getStringArrayExtra(
16986                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
16987                            final int userHandle = intent.getIntExtra(
16988                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
16989
16990                            synchronized(ActivityManagerService.this) {
16991                                mRecentTasks.onPackagesSuspendedChanged(
16992                                        packageNames, suspended, userHandle);
16993                            }
16994                            break;
16995                    }
16996                    break;
16997                case Intent.ACTION_PACKAGE_ADDED:
16998                    // Special case for adding a package: by default turn on compatibility mode.
16999                    Uri data = intent.getData();
17000                    String ssp;
17001                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17002                        final boolean replacing =
17003                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17004                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17005
17006                        try {
17007                            ApplicationInfo ai = AppGlobals.getPackageManager().
17008                                    getApplicationInfo(ssp, 0, 0);
17009                            mBatteryStatsService.notePackageInstalled(ssp,
17010                                    ai != null ? ai.versionCode : 0);
17011                        } catch (RemoteException e) {
17012                        }
17013                    }
17014                    break;
17015                case Intent.ACTION_TIMEZONE_CHANGED:
17016                    // If this is the time zone changed action, queue up a message that will reset
17017                    // the timezone of all currently running processes. This message will get
17018                    // queued up before the broadcast happens.
17019                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17020                    break;
17021                case Intent.ACTION_TIME_CHANGED:
17022                    // If the user set the time, let all running processes know.
17023                    final int is24Hour =
17024                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17025                                    : 0;
17026                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17027                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17028                    synchronized (stats) {
17029                        stats.noteCurrentTimeChangedLocked();
17030                    }
17031                    break;
17032                case Intent.ACTION_CLEAR_DNS_CACHE:
17033                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17034                    break;
17035                case Proxy.PROXY_CHANGE_ACTION:
17036                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17037                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17038                    break;
17039            }
17040        }
17041
17042        // Add to the sticky list if requested.
17043        if (sticky) {
17044            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17045                    callingPid, callingUid)
17046                    != PackageManager.PERMISSION_GRANTED) {
17047                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17048                        + callingPid + ", uid=" + callingUid
17049                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17050                Slog.w(TAG, msg);
17051                throw new SecurityException(msg);
17052            }
17053            if (requiredPermissions != null && requiredPermissions.length > 0) {
17054                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17055                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17056                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17057            }
17058            if (intent.getComponent() != null) {
17059                throw new SecurityException(
17060                        "Sticky broadcasts can't target a specific component");
17061            }
17062            // We use userId directly here, since the "all" target is maintained
17063            // as a separate set of sticky broadcasts.
17064            if (userId != UserHandle.USER_ALL) {
17065                // But first, if this is not a broadcast to all users, then
17066                // make sure it doesn't conflict with an existing broadcast to
17067                // all users.
17068                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17069                        UserHandle.USER_ALL);
17070                if (stickies != null) {
17071                    ArrayList<Intent> list = stickies.get(intent.getAction());
17072                    if (list != null) {
17073                        int N = list.size();
17074                        int i;
17075                        for (i=0; i<N; i++) {
17076                            if (intent.filterEquals(list.get(i))) {
17077                                throw new IllegalArgumentException(
17078                                        "Sticky broadcast " + intent + " for user "
17079                                        + userId + " conflicts with existing global broadcast");
17080                            }
17081                        }
17082                    }
17083                }
17084            }
17085            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17086            if (stickies == null) {
17087                stickies = new ArrayMap<>();
17088                mStickyBroadcasts.put(userId, stickies);
17089            }
17090            ArrayList<Intent> list = stickies.get(intent.getAction());
17091            if (list == null) {
17092                list = new ArrayList<>();
17093                stickies.put(intent.getAction(), list);
17094            }
17095            final int stickiesCount = list.size();
17096            int i;
17097            for (i = 0; i < stickiesCount; i++) {
17098                if (intent.filterEquals(list.get(i))) {
17099                    // This sticky already exists, replace it.
17100                    list.set(i, new Intent(intent));
17101                    break;
17102                }
17103            }
17104            if (i >= stickiesCount) {
17105                list.add(new Intent(intent));
17106            }
17107        }
17108
17109        int[] users;
17110        if (userId == UserHandle.USER_ALL) {
17111            // Caller wants broadcast to go to all started users.
17112            users = mUserController.getStartedUserArrayLocked();
17113        } else {
17114            // Caller wants broadcast to go to one specific user.
17115            users = new int[] {userId};
17116        }
17117
17118        // Figure out who all will receive this broadcast.
17119        List receivers = null;
17120        List<BroadcastFilter> registeredReceivers = null;
17121        // Need to resolve the intent to interested receivers...
17122        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17123                 == 0) {
17124            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17125        }
17126        if (intent.getComponent() == null) {
17127            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17128                // Query one target user at a time, excluding shell-restricted users
17129                for (int i = 0; i < users.length; i++) {
17130                    if (mUserController.hasUserRestriction(
17131                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17132                        continue;
17133                    }
17134                    List<BroadcastFilter> registeredReceiversForUser =
17135                            mReceiverResolver.queryIntent(intent,
17136                                    resolvedType, false, users[i]);
17137                    if (registeredReceivers == null) {
17138                        registeredReceivers = registeredReceiversForUser;
17139                    } else if (registeredReceiversForUser != null) {
17140                        registeredReceivers.addAll(registeredReceiversForUser);
17141                    }
17142                }
17143            } else {
17144                registeredReceivers = mReceiverResolver.queryIntent(intent,
17145                        resolvedType, false, userId);
17146            }
17147        }
17148
17149        final boolean replacePending =
17150                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17151
17152        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17153                + " replacePending=" + replacePending);
17154
17155        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17156        if (!ordered && NR > 0) {
17157            // If we are not serializing this broadcast, then send the
17158            // registered receivers separately so they don't wait for the
17159            // components to be launched.
17160            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17161            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17162                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17163                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17164                    resultExtras, ordered, sticky, false, userId);
17165            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17166            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17167            if (!replaced) {
17168                queue.enqueueParallelBroadcastLocked(r);
17169                queue.scheduleBroadcastsLocked();
17170            }
17171            registeredReceivers = null;
17172            NR = 0;
17173        }
17174
17175        // Merge into one list.
17176        int ir = 0;
17177        if (receivers != null) {
17178            // A special case for PACKAGE_ADDED: do not allow the package
17179            // being added to see this broadcast.  This prevents them from
17180            // using this as a back door to get run as soon as they are
17181            // installed.  Maybe in the future we want to have a special install
17182            // broadcast or such for apps, but we'd like to deliberately make
17183            // this decision.
17184            String skipPackages[] = null;
17185            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17186                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17187                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17188                Uri data = intent.getData();
17189                if (data != null) {
17190                    String pkgName = data.getSchemeSpecificPart();
17191                    if (pkgName != null) {
17192                        skipPackages = new String[] { pkgName };
17193                    }
17194                }
17195            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17196                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17197            }
17198            if (skipPackages != null && (skipPackages.length > 0)) {
17199                for (String skipPackage : skipPackages) {
17200                    if (skipPackage != null) {
17201                        int NT = receivers.size();
17202                        for (int it=0; it<NT; it++) {
17203                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17204                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17205                                receivers.remove(it);
17206                                it--;
17207                                NT--;
17208                            }
17209                        }
17210                    }
17211                }
17212            }
17213
17214            int NT = receivers != null ? receivers.size() : 0;
17215            int it = 0;
17216            ResolveInfo curt = null;
17217            BroadcastFilter curr = null;
17218            while (it < NT && ir < NR) {
17219                if (curt == null) {
17220                    curt = (ResolveInfo)receivers.get(it);
17221                }
17222                if (curr == null) {
17223                    curr = registeredReceivers.get(ir);
17224                }
17225                if (curr.getPriority() >= curt.priority) {
17226                    // Insert this broadcast record into the final list.
17227                    receivers.add(it, curr);
17228                    ir++;
17229                    curr = null;
17230                    it++;
17231                    NT++;
17232                } else {
17233                    // Skip to the next ResolveInfo in the final list.
17234                    it++;
17235                    curt = null;
17236                }
17237            }
17238        }
17239        while (ir < NR) {
17240            if (receivers == null) {
17241                receivers = new ArrayList();
17242            }
17243            receivers.add(registeredReceivers.get(ir));
17244            ir++;
17245        }
17246
17247        if ((receivers != null && receivers.size() > 0)
17248                || resultTo != null) {
17249            BroadcastQueue queue = broadcastQueueForIntent(intent);
17250            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17251                    callerPackage, callingPid, callingUid, resolvedType,
17252                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17253                    resultData, resultExtras, ordered, sticky, false, userId);
17254
17255            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17256                    + ": prev had " + queue.mOrderedBroadcasts.size());
17257            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17258                    "Enqueueing broadcast " + r.intent.getAction());
17259
17260            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17261            if (!replaced) {
17262                queue.enqueueOrderedBroadcastLocked(r);
17263                queue.scheduleBroadcastsLocked();
17264            }
17265        }
17266
17267        return ActivityManager.BROADCAST_SUCCESS;
17268    }
17269
17270    final Intent verifyBroadcastLocked(Intent intent) {
17271        // Refuse possible leaked file descriptors
17272        if (intent != null && intent.hasFileDescriptors() == true) {
17273            throw new IllegalArgumentException("File descriptors passed in Intent");
17274        }
17275
17276        int flags = intent.getFlags();
17277
17278        if (!mProcessesReady) {
17279            // if the caller really truly claims to know what they're doing, go
17280            // ahead and allow the broadcast without launching any receivers
17281            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17282                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17283            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17284                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17285                        + " before boot completion");
17286                throw new IllegalStateException("Cannot broadcast before boot completed");
17287            }
17288        }
17289
17290        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17291            throw new IllegalArgumentException(
17292                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17293        }
17294
17295        return intent;
17296    }
17297
17298    public final int broadcastIntent(IApplicationThread caller,
17299            Intent intent, String resolvedType, IIntentReceiver resultTo,
17300            int resultCode, String resultData, Bundle resultExtras,
17301            String[] requiredPermissions, int appOp, Bundle bOptions,
17302            boolean serialized, boolean sticky, int userId) {
17303        enforceNotIsolatedCaller("broadcastIntent");
17304        synchronized(this) {
17305            intent = verifyBroadcastLocked(intent);
17306
17307            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17308            final int callingPid = Binder.getCallingPid();
17309            final int callingUid = Binder.getCallingUid();
17310            final long origId = Binder.clearCallingIdentity();
17311            int res = broadcastIntentLocked(callerApp,
17312                    callerApp != null ? callerApp.info.packageName : null,
17313                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17314                    requiredPermissions, appOp, null, serialized, sticky,
17315                    callingPid, callingUid, userId);
17316            Binder.restoreCallingIdentity(origId);
17317            return res;
17318        }
17319    }
17320
17321
17322    int broadcastIntentInPackage(String packageName, int uid,
17323            Intent intent, String resolvedType, IIntentReceiver resultTo,
17324            int resultCode, String resultData, Bundle resultExtras,
17325            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17326            int userId) {
17327        synchronized(this) {
17328            intent = verifyBroadcastLocked(intent);
17329
17330            final long origId = Binder.clearCallingIdentity();
17331            String[] requiredPermissions = requiredPermission == null ? null
17332                    : new String[] {requiredPermission};
17333            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17334                    resultTo, resultCode, resultData, resultExtras,
17335                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17336                    sticky, -1, uid, userId);
17337            Binder.restoreCallingIdentity(origId);
17338            return res;
17339        }
17340    }
17341
17342    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17343        // Refuse possible leaked file descriptors
17344        if (intent != null && intent.hasFileDescriptors() == true) {
17345            throw new IllegalArgumentException("File descriptors passed in Intent");
17346        }
17347
17348        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17349                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17350
17351        synchronized(this) {
17352            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17353                    != PackageManager.PERMISSION_GRANTED) {
17354                String msg = "Permission Denial: unbroadcastIntent() from pid="
17355                        + Binder.getCallingPid()
17356                        + ", uid=" + Binder.getCallingUid()
17357                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17358                Slog.w(TAG, msg);
17359                throw new SecurityException(msg);
17360            }
17361            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17362            if (stickies != null) {
17363                ArrayList<Intent> list = stickies.get(intent.getAction());
17364                if (list != null) {
17365                    int N = list.size();
17366                    int i;
17367                    for (i=0; i<N; i++) {
17368                        if (intent.filterEquals(list.get(i))) {
17369                            list.remove(i);
17370                            break;
17371                        }
17372                    }
17373                    if (list.size() <= 0) {
17374                        stickies.remove(intent.getAction());
17375                    }
17376                }
17377                if (stickies.size() <= 0) {
17378                    mStickyBroadcasts.remove(userId);
17379                }
17380            }
17381        }
17382    }
17383
17384    void backgroundServicesFinishedLocked(int userId) {
17385        for (BroadcastQueue queue : mBroadcastQueues) {
17386            queue.backgroundServicesFinishedLocked(userId);
17387        }
17388    }
17389
17390    public void finishReceiver(IBinder who, int resultCode, String resultData,
17391            Bundle resultExtras, boolean resultAbort, int flags) {
17392        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17393
17394        // Refuse possible leaked file descriptors
17395        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17396            throw new IllegalArgumentException("File descriptors passed in Bundle");
17397        }
17398
17399        final long origId = Binder.clearCallingIdentity();
17400        try {
17401            boolean doNext = false;
17402            BroadcastRecord r;
17403
17404            synchronized(this) {
17405                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17406                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17407                r = queue.getMatchingOrderedReceiver(who);
17408                if (r != null) {
17409                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17410                        resultData, resultExtras, resultAbort, true);
17411                }
17412            }
17413
17414            if (doNext) {
17415                r.queue.processNextBroadcast(false);
17416            }
17417            trimApplications();
17418        } finally {
17419            Binder.restoreCallingIdentity(origId);
17420        }
17421    }
17422
17423    // =========================================================
17424    // INSTRUMENTATION
17425    // =========================================================
17426
17427    public boolean startInstrumentation(ComponentName className,
17428            String profileFile, int flags, Bundle arguments,
17429            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17430            int userId, String abiOverride) {
17431        enforceNotIsolatedCaller("startInstrumentation");
17432        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17433                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17434        // Refuse possible leaked file descriptors
17435        if (arguments != null && arguments.hasFileDescriptors()) {
17436            throw new IllegalArgumentException("File descriptors passed in Bundle");
17437        }
17438
17439        synchronized(this) {
17440            InstrumentationInfo ii = null;
17441            ApplicationInfo ai = null;
17442            try {
17443                ii = mContext.getPackageManager().getInstrumentationInfo(
17444                    className, STOCK_PM_FLAGS);
17445                ai = AppGlobals.getPackageManager().getApplicationInfo(
17446                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17447            } catch (PackageManager.NameNotFoundException e) {
17448            } catch (RemoteException e) {
17449            }
17450            if (ii == null) {
17451                reportStartInstrumentationFailure(watcher, className,
17452                        "Unable to find instrumentation info for: " + className);
17453                return false;
17454            }
17455            if (ai == null) {
17456                reportStartInstrumentationFailure(watcher, className,
17457                        "Unable to find instrumentation target package: " + ii.targetPackage);
17458                return false;
17459            }
17460            if (!ai.hasCode()) {
17461                reportStartInstrumentationFailure(watcher, className,
17462                        "Instrumentation target has no code: " + ii.targetPackage);
17463                return false;
17464            }
17465
17466            int match = mContext.getPackageManager().checkSignatures(
17467                    ii.targetPackage, ii.packageName);
17468            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17469                String msg = "Permission Denial: starting instrumentation "
17470                        + className + " from pid="
17471                        + Binder.getCallingPid()
17472                        + ", uid=" + Binder.getCallingPid()
17473                        + " not allowed because package " + ii.packageName
17474                        + " does not have a signature matching the target "
17475                        + ii.targetPackage;
17476                reportStartInstrumentationFailure(watcher, className, msg);
17477                throw new SecurityException(msg);
17478            }
17479
17480            final long origId = Binder.clearCallingIdentity();
17481            // Instrumentation can kill and relaunch even persistent processes
17482            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17483                    "start instr");
17484            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17485            app.instrumentationClass = className;
17486            app.instrumentationInfo = ai;
17487            app.instrumentationProfileFile = profileFile;
17488            app.instrumentationArguments = arguments;
17489            app.instrumentationWatcher = watcher;
17490            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17491            app.instrumentationResultClass = className;
17492            Binder.restoreCallingIdentity(origId);
17493        }
17494
17495        return true;
17496    }
17497
17498    /**
17499     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17500     * error to the logs, but if somebody is watching, send the report there too.  This enables
17501     * the "am" command to report errors with more information.
17502     *
17503     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17504     * @param cn The component name of the instrumentation.
17505     * @param report The error report.
17506     */
17507    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17508            ComponentName cn, String report) {
17509        Slog.w(TAG, report);
17510        try {
17511            if (watcher != null) {
17512                Bundle results = new Bundle();
17513                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17514                results.putString("Error", report);
17515                watcher.instrumentationStatus(cn, -1, results);
17516            }
17517        } catch (RemoteException e) {
17518            Slog.w(TAG, e);
17519        }
17520    }
17521
17522    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17523        if (app.instrumentationWatcher != null) {
17524            try {
17525                // NOTE:  IInstrumentationWatcher *must* be oneway here
17526                app.instrumentationWatcher.instrumentationFinished(
17527                    app.instrumentationClass,
17528                    resultCode,
17529                    results);
17530            } catch (RemoteException e) {
17531            }
17532        }
17533
17534        // Can't call out of the system process with a lock held, so post a message.
17535        if (app.instrumentationUiAutomationConnection != null) {
17536            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17537                    app.instrumentationUiAutomationConnection).sendToTarget();
17538        }
17539
17540        app.instrumentationWatcher = null;
17541        app.instrumentationUiAutomationConnection = null;
17542        app.instrumentationClass = null;
17543        app.instrumentationInfo = null;
17544        app.instrumentationProfileFile = null;
17545        app.instrumentationArguments = null;
17546
17547        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17548                "finished inst");
17549    }
17550
17551    public void finishInstrumentation(IApplicationThread target,
17552            int resultCode, Bundle results) {
17553        int userId = UserHandle.getCallingUserId();
17554        // Refuse possible leaked file descriptors
17555        if (results != null && results.hasFileDescriptors()) {
17556            throw new IllegalArgumentException("File descriptors passed in Intent");
17557        }
17558
17559        synchronized(this) {
17560            ProcessRecord app = getRecordForAppLocked(target);
17561            if (app == null) {
17562                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17563                return;
17564            }
17565            final long origId = Binder.clearCallingIdentity();
17566            finishInstrumentationLocked(app, resultCode, results);
17567            Binder.restoreCallingIdentity(origId);
17568        }
17569    }
17570
17571    // =========================================================
17572    // CONFIGURATION
17573    // =========================================================
17574
17575    public ConfigurationInfo getDeviceConfigurationInfo() {
17576        ConfigurationInfo config = new ConfigurationInfo();
17577        synchronized (this) {
17578            config.reqTouchScreen = mConfiguration.touchscreen;
17579            config.reqKeyboardType = mConfiguration.keyboard;
17580            config.reqNavigation = mConfiguration.navigation;
17581            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17582                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17583                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17584            }
17585            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17586                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17587                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17588            }
17589            config.reqGlEsVersion = GL_ES_VERSION;
17590        }
17591        return config;
17592    }
17593
17594    ActivityStack getFocusedStack() {
17595        return mStackSupervisor.getFocusedStack();
17596    }
17597
17598    @Override
17599    public int getFocusedStackId() throws RemoteException {
17600        ActivityStack focusedStack = getFocusedStack();
17601        if (focusedStack != null) {
17602            return focusedStack.getStackId();
17603        }
17604        return -1;
17605    }
17606
17607    public Configuration getConfiguration() {
17608        Configuration ci;
17609        synchronized(this) {
17610            ci = new Configuration(mConfiguration);
17611            ci.userSetLocale = false;
17612        }
17613        return ci;
17614    }
17615
17616    @Override
17617    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17618        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17619        synchronized (this) {
17620            mSuppressResizeConfigChanges = suppress;
17621        }
17622    }
17623
17624    @Override
17625    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17626        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17627        if (fromStackId == HOME_STACK_ID) {
17628            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17629        }
17630        synchronized (this) {
17631            final long origId = Binder.clearCallingIdentity();
17632            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17633            if (stack != null) {
17634                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17635                final int size = tasks.size();
17636                if (onTop) {
17637                    for (int i = 0; i < size; i++) {
17638                        mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17639                                FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, !FORCE_FOCUS,
17640                                "moveTasksToFullscreenStack", ANIMATE);
17641                    }
17642                } else {
17643                    for (int i = size - 1; i >= 0; i--) {
17644                        mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17645                                FULLSCREEN_WORKSPACE_STACK_ID, 0);
17646                    }
17647                }
17648            }
17649            Binder.restoreCallingIdentity(origId);
17650        }
17651    }
17652
17653    @Override
17654    public void updatePersistentConfiguration(Configuration values) {
17655        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17656                "updateConfiguration()");
17657        enforceWriteSettingsPermission("updateConfiguration()");
17658        if (values == null) {
17659            throw new NullPointerException("Configuration must not be null");
17660        }
17661
17662        int userId = UserHandle.getCallingUserId();
17663
17664        synchronized(this) {
17665            final long origId = Binder.clearCallingIdentity();
17666            updateConfigurationLocked(values, null, false, true, userId);
17667            Binder.restoreCallingIdentity(origId);
17668        }
17669    }
17670
17671    private void updateFontScaleIfNeeded() {
17672        final int currentUserId;
17673        synchronized(this) {
17674            currentUserId = mUserController.getCurrentUserIdLocked();
17675        }
17676        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17677                FONT_SCALE, 1.0f, currentUserId);
17678        if (mConfiguration.fontScale != scaleFactor) {
17679            final Configuration configuration = mWindowManager.computeNewConfiguration();
17680            configuration.fontScale = scaleFactor;
17681            updatePersistentConfiguration(configuration);
17682        }
17683    }
17684
17685    private void enforceWriteSettingsPermission(String func) {
17686        int uid = Binder.getCallingUid();
17687        if (uid == Process.ROOT_UID) {
17688            return;
17689        }
17690
17691        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17692                Settings.getPackageNameForUid(mContext, uid), false)) {
17693            return;
17694        }
17695
17696        String msg = "Permission Denial: " + func + " from pid="
17697                + Binder.getCallingPid()
17698                + ", uid=" + uid
17699                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17700        Slog.w(TAG, msg);
17701        throw new SecurityException(msg);
17702    }
17703
17704    public void updateConfiguration(Configuration values) {
17705        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17706                "updateConfiguration()");
17707
17708        synchronized(this) {
17709            if (values == null && mWindowManager != null) {
17710                // sentinel: fetch the current configuration from the window manager
17711                values = mWindowManager.computeNewConfiguration();
17712            }
17713
17714            if (mWindowManager != null) {
17715                mProcessList.applyDisplaySize(mWindowManager);
17716            }
17717
17718            final long origId = Binder.clearCallingIdentity();
17719            if (values != null) {
17720                Settings.System.clearConfiguration(values);
17721            }
17722            updateConfigurationLocked(values, null, false);
17723            Binder.restoreCallingIdentity(origId);
17724        }
17725    }
17726
17727    void updateUserConfigurationLocked() {
17728        Configuration configuration = new Configuration(mConfiguration);
17729        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17730                mUserController.getCurrentUserIdLocked());
17731        updateConfigurationLocked(configuration, null, false);
17732    }
17733
17734    boolean updateConfigurationLocked(Configuration values,
17735            ActivityRecord starting, boolean initLocale) {
17736        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17737        return updateConfigurationLocked(values, starting, initLocale, false,
17738                UserHandle.USER_NULL);
17739    }
17740
17741    // To cache the list of supported system locales
17742    private String[] mSupportedSystemLocales = null;
17743
17744    /**
17745     * Do either or both things: (1) change the current configuration, and (2)
17746     * make sure the given activity is running with the (now) current
17747     * configuration.  Returns true if the activity has been left running, or
17748     * false if <var>starting</var> is being destroyed to match the new
17749     * configuration.
17750     *
17751     * @param userId is only used when persistent parameter is set to true to persist configuration
17752     *               for that particular user
17753     */
17754    private boolean updateConfigurationLocked(Configuration values,
17755            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17756        int changes = 0;
17757
17758        if (values != null) {
17759            Configuration newConfig = new Configuration(mConfiguration);
17760            changes = newConfig.updateFrom(values);
17761            if (changes != 0) {
17762                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17763                        "Updating configuration to: " + values);
17764
17765                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17766
17767                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17768                    final Locale locale;
17769                    if (values.getLocales().size() == 1) {
17770                        // This is an optimization to avoid the JNI call when the result of
17771                        // getFirstMatch() does not depend on the supported locales.
17772                        locale = values.getLocales().getPrimary();
17773                    } else {
17774                        if (mSupportedSystemLocales == null) {
17775                            mSupportedSystemLocales =
17776                                    Resources.getSystem().getAssets().getLocales();
17777                        }
17778                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
17779                    }
17780                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
17781                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17782                            locale));
17783                }
17784
17785                mConfigurationSeq++;
17786                if (mConfigurationSeq <= 0) {
17787                    mConfigurationSeq = 1;
17788                }
17789                newConfig.seq = mConfigurationSeq;
17790                mConfiguration = newConfig;
17791                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17792                mUsageStatsService.reportConfigurationChange(newConfig,
17793                        mUserController.getCurrentUserIdLocked());
17794                //mUsageStatsService.noteStartConfig(newConfig);
17795
17796                final Configuration configCopy = new Configuration(mConfiguration);
17797
17798                // TODO: If our config changes, should we auto dismiss any currently
17799                // showing dialogs?
17800                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
17801
17802                AttributeCache ac = AttributeCache.instance();
17803                if (ac != null) {
17804                    ac.updateConfiguration(configCopy);
17805                }
17806
17807                // Make sure all resources in our process are updated
17808                // right now, so that anyone who is going to retrieve
17809                // resource values after we return will be sure to get
17810                // the new ones.  This is especially important during
17811                // boot, where the first config change needs to guarantee
17812                // all resources have that config before following boot
17813                // code is executed.
17814                mSystemThread.applyConfigurationToResources(configCopy);
17815
17816                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17817                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17818                    msg.obj = new Configuration(configCopy);
17819                    msg.arg1 = userId;
17820                    mHandler.sendMessage(msg);
17821                }
17822
17823                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
17824                if (isDensityChange) {
17825                    killAllBackgroundProcesses(Build.VERSION_CODES.N);
17826                }
17827
17828                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17829                    ProcessRecord app = mLruProcesses.get(i);
17830                    try {
17831                        if (app.thread != null) {
17832                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17833                                    + app.processName + " new config " + mConfiguration);
17834                            app.thread.scheduleConfigurationChanged(configCopy);
17835                        }
17836                    } catch (Exception e) {
17837                    }
17838                }
17839                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17840                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17841                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17842                        | Intent.FLAG_RECEIVER_FOREGROUND);
17843                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17844                        null, AppOpsManager.OP_NONE, null, false, false,
17845                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17846                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17847                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17848                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17849                    if (!mProcessesReady) {
17850                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17851                    }
17852                    broadcastIntentLocked(null, null, intent,
17853                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17854                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17855                }
17856            }
17857        }
17858
17859        boolean kept = true;
17860        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17861        // mainStack is null during startup.
17862        if (mainStack != null) {
17863            if (changes != 0 && starting == null) {
17864                // If the configuration changed, and the caller is not already
17865                // in the process of starting an activity, then find the top
17866                // activity to check if its configuration needs to change.
17867                starting = mainStack.topRunningActivityLocked();
17868            }
17869
17870            if (starting != null) {
17871                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17872                // And we need to make sure at this point that all other activities
17873                // are made visible with the correct configuration.
17874                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17875                        !PRESERVE_WINDOWS);
17876            }
17877        }
17878
17879        if (values != null && mWindowManager != null) {
17880            mWindowManager.setNewConfiguration(mConfiguration);
17881        }
17882
17883        return kept;
17884    }
17885
17886    /**
17887     * Decide based on the configuration whether we should shouw the ANR,
17888     * crash, etc dialogs.  The idea is that if there is no affordnace to
17889     * press the on-screen buttons, we shouldn't show the dialog.
17890     *
17891     * A thought: SystemUI might also want to get told about this, the Power
17892     * dialog / global actions also might want different behaviors.
17893     */
17894    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
17895        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17896                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17897                                   && config.navigation == Configuration.NAVIGATION_NONAV);
17898        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
17899                                    == Configuration.UI_MODE_TYPE_CAR);
17900        return inputMethodExists && uiIsNotCarType && !inVrMode;
17901    }
17902
17903    @Override
17904    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17905        synchronized (this) {
17906            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17907            if (srec != null) {
17908                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17909            }
17910        }
17911        return false;
17912    }
17913
17914    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17915            Intent resultData) {
17916
17917        synchronized (this) {
17918            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17919            if (r != null) {
17920                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17921            }
17922            return false;
17923        }
17924    }
17925
17926    public int getLaunchedFromUid(IBinder activityToken) {
17927        ActivityRecord srec;
17928        synchronized (this) {
17929            srec = ActivityRecord.forTokenLocked(activityToken);
17930        }
17931        if (srec == null) {
17932            return -1;
17933        }
17934        return srec.launchedFromUid;
17935    }
17936
17937    public String getLaunchedFromPackage(IBinder activityToken) {
17938        ActivityRecord srec;
17939        synchronized (this) {
17940            srec = ActivityRecord.forTokenLocked(activityToken);
17941        }
17942        if (srec == null) {
17943            return null;
17944        }
17945        return srec.launchedFromPackage;
17946    }
17947
17948    // =========================================================
17949    // LIFETIME MANAGEMENT
17950    // =========================================================
17951
17952    // Returns which broadcast queue the app is the current [or imminent] receiver
17953    // on, or 'null' if the app is not an active broadcast recipient.
17954    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17955        BroadcastRecord r = app.curReceiver;
17956        if (r != null) {
17957            return r.queue;
17958        }
17959
17960        // It's not the current receiver, but it might be starting up to become one
17961        synchronized (this) {
17962            for (BroadcastQueue queue : mBroadcastQueues) {
17963                r = queue.mPendingBroadcast;
17964                if (r != null && r.curApp == app) {
17965                    // found it; report which queue it's in
17966                    return queue;
17967                }
17968            }
17969        }
17970
17971        return null;
17972    }
17973
17974    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17975            ComponentName targetComponent, String targetProcess) {
17976        if (!mTrackingAssociations) {
17977            return null;
17978        }
17979        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17980                = mAssociations.get(targetUid);
17981        if (components == null) {
17982            components = new ArrayMap<>();
17983            mAssociations.put(targetUid, components);
17984        }
17985        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17986        if (sourceUids == null) {
17987            sourceUids = new SparseArray<>();
17988            components.put(targetComponent, sourceUids);
17989        }
17990        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17991        if (sourceProcesses == null) {
17992            sourceProcesses = new ArrayMap<>();
17993            sourceUids.put(sourceUid, sourceProcesses);
17994        }
17995        Association ass = sourceProcesses.get(sourceProcess);
17996        if (ass == null) {
17997            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17998                    targetProcess);
17999            sourceProcesses.put(sourceProcess, ass);
18000        }
18001        ass.mCount++;
18002        ass.mNesting++;
18003        if (ass.mNesting == 1) {
18004            ass.mStartTime = SystemClock.uptimeMillis();
18005        }
18006        return ass;
18007    }
18008
18009    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18010            ComponentName targetComponent) {
18011        if (!mTrackingAssociations) {
18012            return;
18013        }
18014        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18015                = mAssociations.get(targetUid);
18016        if (components == null) {
18017            return;
18018        }
18019        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18020        if (sourceUids == null) {
18021            return;
18022        }
18023        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18024        if (sourceProcesses == null) {
18025            return;
18026        }
18027        Association ass = sourceProcesses.get(sourceProcess);
18028        if (ass == null || ass.mNesting <= 0) {
18029            return;
18030        }
18031        ass.mNesting--;
18032        if (ass.mNesting == 0) {
18033            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18034        }
18035    }
18036
18037    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18038            boolean doingAll, long now) {
18039        if (mAdjSeq == app.adjSeq) {
18040            // This adjustment has already been computed.
18041            return app.curRawAdj;
18042        }
18043
18044        if (app.thread == null) {
18045            app.adjSeq = mAdjSeq;
18046            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18047            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18048            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18049        }
18050
18051        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18052        app.adjSource = null;
18053        app.adjTarget = null;
18054        app.empty = false;
18055        app.cached = false;
18056
18057        final int activitiesSize = app.activities.size();
18058
18059        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18060            // The max adjustment doesn't allow this app to be anything
18061            // below foreground, so it is not worth doing work for it.
18062            app.adjType = "fixed";
18063            app.adjSeq = mAdjSeq;
18064            app.curRawAdj = app.maxAdj;
18065            app.foregroundActivities = false;
18066            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18067            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18068            // System processes can do UI, and when they do we want to have
18069            // them trim their memory after the user leaves the UI.  To
18070            // facilitate this, here we need to determine whether or not it
18071            // is currently showing UI.
18072            app.systemNoUi = true;
18073            if (app == TOP_APP) {
18074                app.systemNoUi = false;
18075            } else if (activitiesSize > 0) {
18076                for (int j = 0; j < activitiesSize; j++) {
18077                    final ActivityRecord r = app.activities.get(j);
18078                    if (r.visible) {
18079                        app.systemNoUi = false;
18080                    }
18081                }
18082            }
18083            if (!app.systemNoUi) {
18084                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18085            }
18086            return (app.curAdj=app.maxAdj);
18087        }
18088
18089        app.systemNoUi = false;
18090
18091        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18092
18093        // Determine the importance of the process, starting with most
18094        // important to least, and assign an appropriate OOM adjustment.
18095        int adj;
18096        int schedGroup;
18097        int procState;
18098        boolean foregroundActivities = false;
18099        BroadcastQueue queue;
18100        if (app == TOP_APP) {
18101            // The last app on the list is the foreground app.
18102            adj = ProcessList.FOREGROUND_APP_ADJ;
18103            schedGroup = Process.THREAD_GROUP_TOP_APP;
18104            app.adjType = "top-activity";
18105            foregroundActivities = true;
18106            procState = PROCESS_STATE_CUR_TOP;
18107        } else if (app.instrumentationClass != null) {
18108            // Don't want to kill running instrumentation.
18109            adj = ProcessList.FOREGROUND_APP_ADJ;
18110            schedGroup = Process.THREAD_GROUP_DEFAULT;
18111            app.adjType = "instrumentation";
18112            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18113        } else if ((queue = isReceivingBroadcast(app)) != null) {
18114            // An app that is currently receiving a broadcast also
18115            // counts as being in the foreground for OOM killer purposes.
18116            // It's placed in a sched group based on the nature of the
18117            // broadcast as reflected by which queue it's active in.
18118            adj = ProcessList.FOREGROUND_APP_ADJ;
18119            schedGroup = (queue == mFgBroadcastQueue)
18120                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18121            app.adjType = "broadcast";
18122            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18123        } else if (app.executingServices.size() > 0) {
18124            // An app that is currently executing a service callback also
18125            // counts as being in the foreground.
18126            adj = ProcessList.FOREGROUND_APP_ADJ;
18127            schedGroup = app.execServicesFg ?
18128                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18129            app.adjType = "exec-service";
18130            procState = ActivityManager.PROCESS_STATE_SERVICE;
18131            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18132        } else {
18133            // As far as we know the process is empty.  We may change our mind later.
18134            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18135            // At this point we don't actually know the adjustment.  Use the cached adj
18136            // value that the caller wants us to.
18137            adj = cachedAdj;
18138            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18139            app.cached = true;
18140            app.empty = true;
18141            app.adjType = "cch-empty";
18142        }
18143
18144        // Examine all activities if not already foreground.
18145        if (!foregroundActivities && activitiesSize > 0) {
18146            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18147            for (int j = 0; j < activitiesSize; j++) {
18148                final ActivityRecord r = app.activities.get(j);
18149                if (r.app != app) {
18150                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18151                            + app + "?!? Using " + r.app + " instead.");
18152                    continue;
18153                }
18154                if (r.visible) {
18155                    // App has a visible activity; only upgrade adjustment.
18156                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18157                        adj = ProcessList.VISIBLE_APP_ADJ;
18158                        app.adjType = "visible";
18159                    }
18160                    if (procState > PROCESS_STATE_CUR_TOP) {
18161                        procState = PROCESS_STATE_CUR_TOP;
18162                    }
18163                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18164                    app.cached = false;
18165                    app.empty = false;
18166                    foregroundActivities = true;
18167                    if (r.task != null && minLayer > 0) {
18168                        final int layer = r.task.mLayerRank;
18169                        if (layer >= 0 && minLayer > layer) {
18170                            minLayer = layer;
18171                        }
18172                    }
18173                    break;
18174                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18175                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18176                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18177                        app.adjType = "pausing";
18178                    }
18179                    if (procState > PROCESS_STATE_CUR_TOP) {
18180                        procState = PROCESS_STATE_CUR_TOP;
18181                    }
18182                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18183                    app.cached = false;
18184                    app.empty = false;
18185                    foregroundActivities = true;
18186                } else if (r.state == ActivityState.STOPPING) {
18187                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18188                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18189                        app.adjType = "stopping";
18190                    }
18191                    // For the process state, we will at this point consider the
18192                    // process to be cached.  It will be cached either as an activity
18193                    // or empty depending on whether the activity is finishing.  We do
18194                    // this so that we can treat the process as cached for purposes of
18195                    // memory trimming (determing current memory level, trim command to
18196                    // send to process) since there can be an arbitrary number of stopping
18197                    // processes and they should soon all go into the cached state.
18198                    if (!r.finishing) {
18199                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18200                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18201                        }
18202                    }
18203                    app.cached = false;
18204                    app.empty = false;
18205                    foregroundActivities = true;
18206                } else {
18207                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18208                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18209                        app.adjType = "cch-act";
18210                    }
18211                }
18212            }
18213            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18214                adj += minLayer;
18215            }
18216        }
18217
18218        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18219                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18220            if (app.foregroundServices) {
18221                // The user is aware of this app, so make it visible.
18222                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18223                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18224                app.cached = false;
18225                app.adjType = "fg-service";
18226                schedGroup = Process.THREAD_GROUP_DEFAULT;
18227            } else if (app.forcingToForeground != null) {
18228                // The user is aware of this app, so make it visible.
18229                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18230                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18231                app.cached = false;
18232                app.adjType = "force-fg";
18233                app.adjSource = app.forcingToForeground;
18234                schedGroup = Process.THREAD_GROUP_DEFAULT;
18235            }
18236        }
18237
18238        if (app == mHeavyWeightProcess) {
18239            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18240                // We don't want to kill the current heavy-weight process.
18241                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18242                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18243                app.cached = false;
18244                app.adjType = "heavy";
18245            }
18246            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18247                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18248            }
18249        }
18250
18251        if (app == mHomeProcess) {
18252            if (adj > ProcessList.HOME_APP_ADJ) {
18253                // This process is hosting what we currently consider to be the
18254                // home app, so we don't want to let it go into the background.
18255                adj = ProcessList.HOME_APP_ADJ;
18256                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18257                app.cached = false;
18258                app.adjType = "home";
18259            }
18260            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18261                procState = ActivityManager.PROCESS_STATE_HOME;
18262            }
18263        }
18264
18265        if (app == mPreviousProcess && app.activities.size() > 0) {
18266            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18267                // This was the previous process that showed UI to the user.
18268                // We want to try to keep it around more aggressively, to give
18269                // a good experience around switching between two apps.
18270                adj = ProcessList.PREVIOUS_APP_ADJ;
18271                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18272                app.cached = false;
18273                app.adjType = "previous";
18274            }
18275            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18276                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18277            }
18278        }
18279
18280        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18281                + " reason=" + app.adjType);
18282
18283        // By default, we use the computed adjustment.  It may be changed if
18284        // there are applications dependent on our services or providers, but
18285        // this gives us a baseline and makes sure we don't get into an
18286        // infinite recursion.
18287        app.adjSeq = mAdjSeq;
18288        app.curRawAdj = adj;
18289        app.hasStartedServices = false;
18290
18291        if (mBackupTarget != null && app == mBackupTarget.app) {
18292            // If possible we want to avoid killing apps while they're being backed up
18293            if (adj > ProcessList.BACKUP_APP_ADJ) {
18294                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18295                adj = ProcessList.BACKUP_APP_ADJ;
18296                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18297                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18298                }
18299                app.adjType = "backup";
18300                app.cached = false;
18301            }
18302            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18303                procState = ActivityManager.PROCESS_STATE_BACKUP;
18304            }
18305        }
18306
18307        boolean mayBeTop = false;
18308
18309        for (int is = app.services.size()-1;
18310                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18311                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18312                        || procState > ActivityManager.PROCESS_STATE_TOP);
18313                is--) {
18314            ServiceRecord s = app.services.valueAt(is);
18315            if (s.startRequested) {
18316                app.hasStartedServices = true;
18317                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18318                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18319                }
18320                if (app.hasShownUi && app != mHomeProcess) {
18321                    // If this process has shown some UI, let it immediately
18322                    // go to the LRU list because it may be pretty heavy with
18323                    // UI stuff.  We'll tag it with a label just to help
18324                    // debug and understand what is going on.
18325                    if (adj > ProcessList.SERVICE_ADJ) {
18326                        app.adjType = "cch-started-ui-services";
18327                    }
18328                } else {
18329                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18330                        // This service has seen some activity within
18331                        // recent memory, so we will keep its process ahead
18332                        // of the background processes.
18333                        if (adj > ProcessList.SERVICE_ADJ) {
18334                            adj = ProcessList.SERVICE_ADJ;
18335                            app.adjType = "started-services";
18336                            app.cached = false;
18337                        }
18338                    }
18339                    // If we have let the service slide into the background
18340                    // state, still have some text describing what it is doing
18341                    // even though the service no longer has an impact.
18342                    if (adj > ProcessList.SERVICE_ADJ) {
18343                        app.adjType = "cch-started-services";
18344                    }
18345                }
18346            }
18347            for (int conni = s.connections.size()-1;
18348                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18349                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18350                            || procState > ActivityManager.PROCESS_STATE_TOP);
18351                    conni--) {
18352                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18353                for (int i = 0;
18354                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18355                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18356                                || procState > ActivityManager.PROCESS_STATE_TOP);
18357                        i++) {
18358                    // XXX should compute this based on the max of
18359                    // all connected clients.
18360                    ConnectionRecord cr = clist.get(i);
18361                    if (cr.binding.client == app) {
18362                        // Binding to ourself is not interesting.
18363                        continue;
18364                    }
18365                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18366                        ProcessRecord client = cr.binding.client;
18367                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18368                                TOP_APP, doingAll, now);
18369                        int clientProcState = client.curProcState;
18370                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18371                            // If the other app is cached for any reason, for purposes here
18372                            // we are going to consider it empty.  The specific cached state
18373                            // doesn't propagate except under certain conditions.
18374                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18375                        }
18376                        String adjType = null;
18377                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18378                            // Not doing bind OOM management, so treat
18379                            // this guy more like a started service.
18380                            if (app.hasShownUi && app != mHomeProcess) {
18381                                // If this process has shown some UI, let it immediately
18382                                // go to the LRU list because it may be pretty heavy with
18383                                // UI stuff.  We'll tag it with a label just to help
18384                                // debug and understand what is going on.
18385                                if (adj > clientAdj) {
18386                                    adjType = "cch-bound-ui-services";
18387                                }
18388                                app.cached = false;
18389                                clientAdj = adj;
18390                                clientProcState = procState;
18391                            } else {
18392                                if (now >= (s.lastActivity
18393                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18394                                    // This service has not seen activity within
18395                                    // recent memory, so allow it to drop to the
18396                                    // LRU list if there is no other reason to keep
18397                                    // it around.  We'll also tag it with a label just
18398                                    // to help debug and undertand what is going on.
18399                                    if (adj > clientAdj) {
18400                                        adjType = "cch-bound-services";
18401                                    }
18402                                    clientAdj = adj;
18403                                }
18404                            }
18405                        }
18406                        if (adj > clientAdj) {
18407                            // If this process has recently shown UI, and
18408                            // the process that is binding to it is less
18409                            // important than being visible, then we don't
18410                            // care about the binding as much as we care
18411                            // about letting this process get into the LRU
18412                            // list to be killed and restarted if needed for
18413                            // memory.
18414                            if (app.hasShownUi && app != mHomeProcess
18415                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18416                                adjType = "cch-bound-ui-services";
18417                            } else {
18418                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18419                                        |Context.BIND_IMPORTANT)) != 0) {
18420                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18421                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18422                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18423                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18424                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18425                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18426                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18427                                    adj = clientAdj;
18428                                } else {
18429                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18430                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18431                                    }
18432                                }
18433                                if (!client.cached) {
18434                                    app.cached = false;
18435                                }
18436                                adjType = "service";
18437                            }
18438                        }
18439                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18440                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18441                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18442                            }
18443                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18444                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18445                                    // Special handling of clients who are in the top state.
18446                                    // We *may* want to consider this process to be in the
18447                                    // top state as well, but only if there is not another
18448                                    // reason for it to be running.  Being on the top is a
18449                                    // special state, meaning you are specifically running
18450                                    // for the current top app.  If the process is already
18451                                    // running in the background for some other reason, it
18452                                    // is more important to continue considering it to be
18453                                    // in the background state.
18454                                    mayBeTop = true;
18455                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18456                                } else {
18457                                    // Special handling for above-top states (persistent
18458                                    // processes).  These should not bring the current process
18459                                    // into the top state, since they are not on top.  Instead
18460                                    // give them the best state after that.
18461                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18462                                        clientProcState =
18463                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18464                                    } else if (mWakefulness
18465                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18466                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18467                                                    != 0) {
18468                                        clientProcState =
18469                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18470                                    } else {
18471                                        clientProcState =
18472                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18473                                    }
18474                                }
18475                            }
18476                        } else {
18477                            if (clientProcState <
18478                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18479                                clientProcState =
18480                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18481                            }
18482                        }
18483                        if (procState > clientProcState) {
18484                            procState = clientProcState;
18485                        }
18486                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18487                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18488                            app.pendingUiClean = true;
18489                        }
18490                        if (adjType != null) {
18491                            app.adjType = adjType;
18492                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18493                                    .REASON_SERVICE_IN_USE;
18494                            app.adjSource = cr.binding.client;
18495                            app.adjSourceProcState = clientProcState;
18496                            app.adjTarget = s.name;
18497                        }
18498                    }
18499                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18500                        app.treatLikeActivity = true;
18501                    }
18502                    final ActivityRecord a = cr.activity;
18503                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18504                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18505                                (a.visible || a.state == ActivityState.RESUMED
18506                                 || a.state == ActivityState.PAUSING)) {
18507                            adj = ProcessList.FOREGROUND_APP_ADJ;
18508                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18509                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18510                            }
18511                            app.cached = false;
18512                            app.adjType = "service";
18513                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18514                                    .REASON_SERVICE_IN_USE;
18515                            app.adjSource = a;
18516                            app.adjSourceProcState = procState;
18517                            app.adjTarget = s.name;
18518                        }
18519                    }
18520                }
18521            }
18522        }
18523
18524        for (int provi = app.pubProviders.size()-1;
18525                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18526                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18527                        || procState > ActivityManager.PROCESS_STATE_TOP);
18528                provi--) {
18529            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18530            for (int i = cpr.connections.size()-1;
18531                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18532                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18533                            || procState > ActivityManager.PROCESS_STATE_TOP);
18534                    i--) {
18535                ContentProviderConnection conn = cpr.connections.get(i);
18536                ProcessRecord client = conn.client;
18537                if (client == app) {
18538                    // Being our own client is not interesting.
18539                    continue;
18540                }
18541                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18542                int clientProcState = client.curProcState;
18543                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18544                    // If the other app is cached for any reason, for purposes here
18545                    // we are going to consider it empty.
18546                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18547                }
18548                if (adj > clientAdj) {
18549                    if (app.hasShownUi && app != mHomeProcess
18550                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18551                        app.adjType = "cch-ui-provider";
18552                    } else {
18553                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18554                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18555                        app.adjType = "provider";
18556                    }
18557                    app.cached &= client.cached;
18558                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18559                            .REASON_PROVIDER_IN_USE;
18560                    app.adjSource = client;
18561                    app.adjSourceProcState = clientProcState;
18562                    app.adjTarget = cpr.name;
18563                }
18564                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18565                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18566                        // Special handling of clients who are in the top state.
18567                        // We *may* want to consider this process to be in the
18568                        // top state as well, but only if there is not another
18569                        // reason for it to be running.  Being on the top is a
18570                        // special state, meaning you are specifically running
18571                        // for the current top app.  If the process is already
18572                        // running in the background for some other reason, it
18573                        // is more important to continue considering it to be
18574                        // in the background state.
18575                        mayBeTop = true;
18576                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18577                    } else {
18578                        // Special handling for above-top states (persistent
18579                        // processes).  These should not bring the current process
18580                        // into the top state, since they are not on top.  Instead
18581                        // give them the best state after that.
18582                        clientProcState =
18583                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18584                    }
18585                }
18586                if (procState > clientProcState) {
18587                    procState = clientProcState;
18588                }
18589                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18590                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18591                }
18592            }
18593            // If the provider has external (non-framework) process
18594            // dependencies, ensure that its adjustment is at least
18595            // FOREGROUND_APP_ADJ.
18596            if (cpr.hasExternalProcessHandles()) {
18597                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18598                    adj = ProcessList.FOREGROUND_APP_ADJ;
18599                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18600                    app.cached = false;
18601                    app.adjType = "provider";
18602                    app.adjTarget = cpr.name;
18603                }
18604                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18605                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18606                }
18607            }
18608        }
18609
18610        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18611            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18612                adj = ProcessList.PREVIOUS_APP_ADJ;
18613                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18614                app.cached = false;
18615                app.adjType = "provider";
18616            }
18617            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18618                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18619            }
18620        }
18621
18622        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18623            // A client of one of our services or providers is in the top state.  We
18624            // *may* want to be in the top state, but not if we are already running in
18625            // the background for some other reason.  For the decision here, we are going
18626            // to pick out a few specific states that we want to remain in when a client
18627            // is top (states that tend to be longer-term) and otherwise allow it to go
18628            // to the top state.
18629            switch (procState) {
18630                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18631                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18632                case ActivityManager.PROCESS_STATE_SERVICE:
18633                    // These all are longer-term states, so pull them up to the top
18634                    // of the background states, but not all the way to the top state.
18635                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18636                    break;
18637                default:
18638                    // Otherwise, top is a better choice, so take it.
18639                    procState = ActivityManager.PROCESS_STATE_TOP;
18640                    break;
18641            }
18642        }
18643
18644        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18645            if (app.hasClientActivities) {
18646                // This is a cached process, but with client activities.  Mark it so.
18647                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18648                app.adjType = "cch-client-act";
18649            } else if (app.treatLikeActivity) {
18650                // This is a cached process, but somebody wants us to treat it like it has
18651                // an activity, okay!
18652                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18653                app.adjType = "cch-as-act";
18654            }
18655        }
18656
18657        if (adj == ProcessList.SERVICE_ADJ) {
18658            if (doingAll) {
18659                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18660                mNewNumServiceProcs++;
18661                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18662                if (!app.serviceb) {
18663                    // This service isn't far enough down on the LRU list to
18664                    // normally be a B service, but if we are low on RAM and it
18665                    // is large we want to force it down since we would prefer to
18666                    // keep launcher over it.
18667                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18668                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18669                        app.serviceHighRam = true;
18670                        app.serviceb = true;
18671                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18672                    } else {
18673                        mNewNumAServiceProcs++;
18674                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18675                    }
18676                } else {
18677                    app.serviceHighRam = false;
18678                }
18679            }
18680            if (app.serviceb) {
18681                adj = ProcessList.SERVICE_B_ADJ;
18682            }
18683        }
18684
18685        app.curRawAdj = adj;
18686
18687        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18688        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18689        if (adj > app.maxAdj) {
18690            adj = app.maxAdj;
18691            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18692                schedGroup = Process.THREAD_GROUP_DEFAULT;
18693            }
18694        }
18695
18696        // Do final modification to adj.  Everything we do between here and applying
18697        // the final setAdj must be done in this function, because we will also use
18698        // it when computing the final cached adj later.  Note that we don't need to
18699        // worry about this for max adj above, since max adj will always be used to
18700        // keep it out of the cached vaues.
18701        app.curAdj = app.modifyRawOomAdj(adj);
18702        app.curSchedGroup = schedGroup;
18703        app.curProcState = procState;
18704        app.foregroundActivities = foregroundActivities;
18705
18706        return app.curRawAdj;
18707    }
18708
18709    /**
18710     * Record new PSS sample for a process.
18711     */
18712    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
18713            long now) {
18714        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
18715                swapPss * 1024);
18716        proc.lastPssTime = now;
18717        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18718        if (DEBUG_PSS) Slog.d(TAG_PSS,
18719                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18720                + " state=" + ProcessList.makeProcStateString(procState));
18721        if (proc.initialIdlePss == 0) {
18722            proc.initialIdlePss = pss;
18723        }
18724        proc.lastPss = pss;
18725        proc.lastSwapPss = swapPss;
18726        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18727            proc.lastCachedPss = pss;
18728            proc.lastCachedSwapPss = swapPss;
18729        }
18730
18731        final SparseArray<Pair<Long, String>> watchUids
18732                = mMemWatchProcesses.getMap().get(proc.processName);
18733        Long check = null;
18734        if (watchUids != null) {
18735            Pair<Long, String> val = watchUids.get(proc.uid);
18736            if (val == null) {
18737                val = watchUids.get(0);
18738            }
18739            if (val != null) {
18740                check = val.first;
18741            }
18742        }
18743        if (check != null) {
18744            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18745                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18746                if (!isDebuggable) {
18747                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18748                        isDebuggable = true;
18749                    }
18750                }
18751                if (isDebuggable) {
18752                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18753                    final ProcessRecord myProc = proc;
18754                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18755                    mMemWatchDumpProcName = proc.processName;
18756                    mMemWatchDumpFile = heapdumpFile.toString();
18757                    mMemWatchDumpPid = proc.pid;
18758                    mMemWatchDumpUid = proc.uid;
18759                    BackgroundThread.getHandler().post(new Runnable() {
18760                        @Override
18761                        public void run() {
18762                            revokeUriPermission(ActivityThread.currentActivityThread()
18763                                            .getApplicationThread(),
18764                                    DumpHeapActivity.JAVA_URI,
18765                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18766                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18767                                    UserHandle.myUserId());
18768                            ParcelFileDescriptor fd = null;
18769                            try {
18770                                heapdumpFile.delete();
18771                                fd = ParcelFileDescriptor.open(heapdumpFile,
18772                                        ParcelFileDescriptor.MODE_CREATE |
18773                                                ParcelFileDescriptor.MODE_TRUNCATE |
18774                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18775                                                ParcelFileDescriptor.MODE_APPEND);
18776                                IApplicationThread thread = myProc.thread;
18777                                if (thread != null) {
18778                                    try {
18779                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18780                                                "Requesting dump heap from "
18781                                                + myProc + " to " + heapdumpFile);
18782                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18783                                    } catch (RemoteException e) {
18784                                    }
18785                                }
18786                            } catch (FileNotFoundException e) {
18787                                e.printStackTrace();
18788                            } finally {
18789                                if (fd != null) {
18790                                    try {
18791                                        fd.close();
18792                                    } catch (IOException e) {
18793                                    }
18794                                }
18795                            }
18796                        }
18797                    });
18798                } else {
18799                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18800                            + ", but debugging not enabled");
18801                }
18802            }
18803        }
18804    }
18805
18806    /**
18807     * Schedule PSS collection of a process.
18808     */
18809    void requestPssLocked(ProcessRecord proc, int procState) {
18810        if (mPendingPssProcesses.contains(proc)) {
18811            return;
18812        }
18813        if (mPendingPssProcesses.size() == 0) {
18814            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18815        }
18816        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18817        proc.pssProcState = procState;
18818        mPendingPssProcesses.add(proc);
18819    }
18820
18821    /**
18822     * Schedule PSS collection of all processes.
18823     */
18824    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18825        if (!always) {
18826            if (now < (mLastFullPssTime +
18827                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18828                return;
18829            }
18830        }
18831        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18832        mLastFullPssTime = now;
18833        mFullPssPending = true;
18834        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18835        mPendingPssProcesses.clear();
18836        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18837            ProcessRecord app = mLruProcesses.get(i);
18838            if (app.thread == null
18839                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18840                continue;
18841            }
18842            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18843                app.pssProcState = app.setProcState;
18844                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18845                        mTestPssMode, isSleeping(), now);
18846                mPendingPssProcesses.add(app);
18847            }
18848        }
18849        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18850    }
18851
18852    public void setTestPssMode(boolean enabled) {
18853        synchronized (this) {
18854            mTestPssMode = enabled;
18855            if (enabled) {
18856                // Whenever we enable the mode, we want to take a snapshot all of current
18857                // process mem use.
18858                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18859            }
18860        }
18861    }
18862
18863    /**
18864     * Ask a given process to GC right now.
18865     */
18866    final void performAppGcLocked(ProcessRecord app) {
18867        try {
18868            app.lastRequestedGc = SystemClock.uptimeMillis();
18869            if (app.thread != null) {
18870                if (app.reportLowMemory) {
18871                    app.reportLowMemory = false;
18872                    app.thread.scheduleLowMemory();
18873                } else {
18874                    app.thread.processInBackground();
18875                }
18876            }
18877        } catch (Exception e) {
18878            // whatever.
18879        }
18880    }
18881
18882    /**
18883     * Returns true if things are idle enough to perform GCs.
18884     */
18885    private final boolean canGcNowLocked() {
18886        boolean processingBroadcasts = false;
18887        for (BroadcastQueue q : mBroadcastQueues) {
18888            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18889                processingBroadcasts = true;
18890            }
18891        }
18892        return !processingBroadcasts
18893                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18894    }
18895
18896    /**
18897     * Perform GCs on all processes that are waiting for it, but only
18898     * if things are idle.
18899     */
18900    final void performAppGcsLocked() {
18901        final int N = mProcessesToGc.size();
18902        if (N <= 0) {
18903            return;
18904        }
18905        if (canGcNowLocked()) {
18906            while (mProcessesToGc.size() > 0) {
18907                ProcessRecord proc = mProcessesToGc.remove(0);
18908                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18909                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18910                            <= SystemClock.uptimeMillis()) {
18911                        // To avoid spamming the system, we will GC processes one
18912                        // at a time, waiting a few seconds between each.
18913                        performAppGcLocked(proc);
18914                        scheduleAppGcsLocked();
18915                        return;
18916                    } else {
18917                        // It hasn't been long enough since we last GCed this
18918                        // process...  put it in the list to wait for its time.
18919                        addProcessToGcListLocked(proc);
18920                        break;
18921                    }
18922                }
18923            }
18924
18925            scheduleAppGcsLocked();
18926        }
18927    }
18928
18929    /**
18930     * If all looks good, perform GCs on all processes waiting for them.
18931     */
18932    final void performAppGcsIfAppropriateLocked() {
18933        if (canGcNowLocked()) {
18934            performAppGcsLocked();
18935            return;
18936        }
18937        // Still not idle, wait some more.
18938        scheduleAppGcsLocked();
18939    }
18940
18941    /**
18942     * Schedule the execution of all pending app GCs.
18943     */
18944    final void scheduleAppGcsLocked() {
18945        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18946
18947        if (mProcessesToGc.size() > 0) {
18948            // Schedule a GC for the time to the next process.
18949            ProcessRecord proc = mProcessesToGc.get(0);
18950            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18951
18952            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18953            long now = SystemClock.uptimeMillis();
18954            if (when < (now+GC_TIMEOUT)) {
18955                when = now + GC_TIMEOUT;
18956            }
18957            mHandler.sendMessageAtTime(msg, when);
18958        }
18959    }
18960
18961    /**
18962     * Add a process to the array of processes waiting to be GCed.  Keeps the
18963     * list in sorted order by the last GC time.  The process can't already be
18964     * on the list.
18965     */
18966    final void addProcessToGcListLocked(ProcessRecord proc) {
18967        boolean added = false;
18968        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18969            if (mProcessesToGc.get(i).lastRequestedGc <
18970                    proc.lastRequestedGc) {
18971                added = true;
18972                mProcessesToGc.add(i+1, proc);
18973                break;
18974            }
18975        }
18976        if (!added) {
18977            mProcessesToGc.add(0, proc);
18978        }
18979    }
18980
18981    /**
18982     * Set up to ask a process to GC itself.  This will either do it
18983     * immediately, or put it on the list of processes to gc the next
18984     * time things are idle.
18985     */
18986    final void scheduleAppGcLocked(ProcessRecord app) {
18987        long now = SystemClock.uptimeMillis();
18988        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18989            return;
18990        }
18991        if (!mProcessesToGc.contains(app)) {
18992            addProcessToGcListLocked(app);
18993            scheduleAppGcsLocked();
18994        }
18995    }
18996
18997    final void checkExcessivePowerUsageLocked(boolean doKills) {
18998        updateCpuStatsNow();
18999
19000        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19001        boolean doWakeKills = doKills;
19002        boolean doCpuKills = doKills;
19003        if (mLastPowerCheckRealtime == 0) {
19004            doWakeKills = false;
19005        }
19006        if (mLastPowerCheckUptime == 0) {
19007            doCpuKills = false;
19008        }
19009        if (stats.isScreenOn()) {
19010            doWakeKills = false;
19011        }
19012        final long curRealtime = SystemClock.elapsedRealtime();
19013        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19014        final long curUptime = SystemClock.uptimeMillis();
19015        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19016        mLastPowerCheckRealtime = curRealtime;
19017        mLastPowerCheckUptime = curUptime;
19018        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19019            doWakeKills = false;
19020        }
19021        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19022            doCpuKills = false;
19023        }
19024        int i = mLruProcesses.size();
19025        while (i > 0) {
19026            i--;
19027            ProcessRecord app = mLruProcesses.get(i);
19028            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19029                long wtime;
19030                synchronized (stats) {
19031                    wtime = stats.getProcessWakeTime(app.info.uid,
19032                            app.pid, curRealtime);
19033                }
19034                long wtimeUsed = wtime - app.lastWakeTime;
19035                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19036                if (DEBUG_POWER) {
19037                    StringBuilder sb = new StringBuilder(128);
19038                    sb.append("Wake for ");
19039                    app.toShortString(sb);
19040                    sb.append(": over ");
19041                    TimeUtils.formatDuration(realtimeSince, sb);
19042                    sb.append(" used ");
19043                    TimeUtils.formatDuration(wtimeUsed, sb);
19044                    sb.append(" (");
19045                    sb.append((wtimeUsed*100)/realtimeSince);
19046                    sb.append("%)");
19047                    Slog.i(TAG_POWER, sb.toString());
19048                    sb.setLength(0);
19049                    sb.append("CPU for ");
19050                    app.toShortString(sb);
19051                    sb.append(": over ");
19052                    TimeUtils.formatDuration(uptimeSince, sb);
19053                    sb.append(" used ");
19054                    TimeUtils.formatDuration(cputimeUsed, sb);
19055                    sb.append(" (");
19056                    sb.append((cputimeUsed*100)/uptimeSince);
19057                    sb.append("%)");
19058                    Slog.i(TAG_POWER, sb.toString());
19059                }
19060                // If a process has held a wake lock for more
19061                // than 50% of the time during this period,
19062                // that sounds bad.  Kill!
19063                if (doWakeKills && realtimeSince > 0
19064                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19065                    synchronized (stats) {
19066                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19067                                realtimeSince, wtimeUsed);
19068                    }
19069                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19070                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19071                } else if (doCpuKills && uptimeSince > 0
19072                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19073                    synchronized (stats) {
19074                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19075                                uptimeSince, cputimeUsed);
19076                    }
19077                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19078                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19079                } else {
19080                    app.lastWakeTime = wtime;
19081                    app.lastCpuTime = app.curCpuTime;
19082                }
19083            }
19084        }
19085    }
19086
19087    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19088            long nowElapsed) {
19089        boolean success = true;
19090
19091        if (app.curRawAdj != app.setRawAdj) {
19092            app.setRawAdj = app.curRawAdj;
19093        }
19094
19095        int changes = 0;
19096
19097        if (app.curAdj != app.setAdj) {
19098            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19099            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19100                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19101                    + app.adjType);
19102            app.setAdj = app.curAdj;
19103        }
19104
19105        if (app.setSchedGroup != app.curSchedGroup) {
19106            app.setSchedGroup = app.curSchedGroup;
19107            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19108                    "Setting process group of " + app.processName
19109                    + " to " + app.curSchedGroup);
19110            if (app.waitingToKill != null && app.curReceiver == null
19111                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19112                app.kill(app.waitingToKill, true);
19113                success = false;
19114            } else {
19115                if (true) {
19116                    long oldId = Binder.clearCallingIdentity();
19117                    try {
19118                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19119                    } catch (Exception e) {
19120                        Slog.w(TAG, "Failed setting process group of " + app.pid
19121                                + " to " + app.curSchedGroup);
19122                        e.printStackTrace();
19123                    } finally {
19124                        Binder.restoreCallingIdentity(oldId);
19125                    }
19126                } else {
19127                    if (app.thread != null) {
19128                        try {
19129                            app.thread.setSchedulingGroup(app.curSchedGroup);
19130                        } catch (RemoteException e) {
19131                        }
19132                    }
19133                }
19134            }
19135        }
19136        if (app.repForegroundActivities != app.foregroundActivities) {
19137            app.repForegroundActivities = app.foregroundActivities;
19138            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19139        }
19140        if (app.repProcState != app.curProcState) {
19141            app.repProcState = app.curProcState;
19142            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19143            if (app.thread != null) {
19144                try {
19145                    if (false) {
19146                        //RuntimeException h = new RuntimeException("here");
19147                        Slog.i(TAG, "Sending new process state " + app.repProcState
19148                                + " to " + app /*, h*/);
19149                    }
19150                    app.thread.setProcessState(app.repProcState);
19151                } catch (RemoteException e) {
19152                }
19153            }
19154        }
19155        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19156                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19157            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19158                // Experimental code to more aggressively collect pss while
19159                // running test...  the problem is that this tends to collect
19160                // the data right when a process is transitioning between process
19161                // states, which well tend to give noisy data.
19162                long start = SystemClock.uptimeMillis();
19163                long pss = Debug.getPss(app.pid, mTmpLong, null);
19164                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19165                mPendingPssProcesses.remove(app);
19166                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19167                        + " to " + app.curProcState + ": "
19168                        + (SystemClock.uptimeMillis()-start) + "ms");
19169            }
19170            app.lastStateTime = now;
19171            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19172                    mTestPssMode, isSleeping(), now);
19173            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19174                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19175                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19176                    + (app.nextPssTime-now) + ": " + app);
19177        } else {
19178            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19179                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19180                    mTestPssMode)))) {
19181                requestPssLocked(app, app.setProcState);
19182                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19183                        mTestPssMode, isSleeping(), now);
19184            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19185                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19186        }
19187        if (app.setProcState != app.curProcState) {
19188            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19189                    "Proc state change of " + app.processName
19190                            + " to " + app.curProcState);
19191            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19192            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19193            if (setImportant && !curImportant) {
19194                // This app is no longer something we consider important enough to allow to
19195                // use arbitrary amounts of battery power.  Note
19196                // its current wake lock time to later know to kill it if
19197                // it is not behaving well.
19198                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19199                synchronized (stats) {
19200                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19201                            app.pid, nowElapsed);
19202                }
19203                app.lastCpuTime = app.curCpuTime;
19204
19205            }
19206            // Inform UsageStats of important process state change
19207            // Must be called before updating setProcState
19208            maybeUpdateUsageStatsLocked(app, nowElapsed);
19209
19210            app.setProcState = app.curProcState;
19211            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19212                app.notCachedSinceIdle = false;
19213            }
19214            if (!doingAll) {
19215                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19216            } else {
19217                app.procStateChanged = true;
19218            }
19219        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19220                > USAGE_STATS_INTERACTION_INTERVAL) {
19221            // For apps that sit around for a long time in the interactive state, we need
19222            // to report this at least once a day so they don't go idle.
19223            maybeUpdateUsageStatsLocked(app, nowElapsed);
19224        }
19225
19226        if (changes != 0) {
19227            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19228                    "Changes in " + app + ": " + changes);
19229            int i = mPendingProcessChanges.size()-1;
19230            ProcessChangeItem item = null;
19231            while (i >= 0) {
19232                item = mPendingProcessChanges.get(i);
19233                if (item.pid == app.pid) {
19234                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19235                            "Re-using existing item: " + item);
19236                    break;
19237                }
19238                i--;
19239            }
19240            if (i < 0) {
19241                // No existing item in pending changes; need a new one.
19242                final int NA = mAvailProcessChanges.size();
19243                if (NA > 0) {
19244                    item = mAvailProcessChanges.remove(NA-1);
19245                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19246                            "Retrieving available item: " + item);
19247                } else {
19248                    item = new ProcessChangeItem();
19249                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19250                            "Allocating new item: " + item);
19251                }
19252                item.changes = 0;
19253                item.pid = app.pid;
19254                item.uid = app.info.uid;
19255                if (mPendingProcessChanges.size() == 0) {
19256                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19257                            "*** Enqueueing dispatch processes changed!");
19258                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19259                }
19260                mPendingProcessChanges.add(item);
19261            }
19262            item.changes |= changes;
19263            item.processState = app.repProcState;
19264            item.foregroundActivities = app.repForegroundActivities;
19265            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19266                    "Item " + Integer.toHexString(System.identityHashCode(item))
19267                    + " " + app.toShortString() + ": changes=" + item.changes
19268                    + " procState=" + item.processState
19269                    + " foreground=" + item.foregroundActivities
19270                    + " type=" + app.adjType + " source=" + app.adjSource
19271                    + " target=" + app.adjTarget);
19272        }
19273
19274        return success;
19275    }
19276
19277    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19278        final UidRecord.ChangeItem pendingChange;
19279        if (uidRec == null || uidRec.pendingChange == null) {
19280            if (mPendingUidChanges.size() == 0) {
19281                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19282                        "*** Enqueueing dispatch uid changed!");
19283                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19284            }
19285            final int NA = mAvailUidChanges.size();
19286            if (NA > 0) {
19287                pendingChange = mAvailUidChanges.remove(NA-1);
19288                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19289                        "Retrieving available item: " + pendingChange);
19290            } else {
19291                pendingChange = new UidRecord.ChangeItem();
19292                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19293                        "Allocating new item: " + pendingChange);
19294            }
19295            if (uidRec != null) {
19296                uidRec.pendingChange = pendingChange;
19297                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19298                    // If this uid is going away, and we haven't yet reported it is gone,
19299                    // then do so now.
19300                    change = UidRecord.CHANGE_GONE_IDLE;
19301                }
19302            } else if (uid < 0) {
19303                throw new IllegalArgumentException("No UidRecord or uid");
19304            }
19305            pendingChange.uidRecord = uidRec;
19306            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19307            mPendingUidChanges.add(pendingChange);
19308        } else {
19309            pendingChange = uidRec.pendingChange;
19310            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19311                change = UidRecord.CHANGE_GONE_IDLE;
19312            }
19313        }
19314        pendingChange.change = change;
19315        pendingChange.processState = uidRec != null
19316                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19317    }
19318
19319    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19320            String authority) {
19321        if (app == null) return;
19322        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19323            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19324            if (userState == null) return;
19325            final long now = SystemClock.elapsedRealtime();
19326            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19327            if (lastReported == null || lastReported < now - 60 * 1000L) {
19328                mUsageStatsService.reportContentProviderUsage(
19329                        authority, providerPkgName, app.userId);
19330                userState.mProviderLastReportedFg.put(authority, now);
19331            }
19332        }
19333    }
19334
19335    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19336        if (DEBUG_USAGE_STATS) {
19337            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19338                    + "] state changes: old = " + app.setProcState + ", new = "
19339                    + app.curProcState);
19340        }
19341        if (mUsageStatsService == null) {
19342            return;
19343        }
19344        boolean isInteraction;
19345        // To avoid some abuse patterns, we are going to be careful about what we consider
19346        // to be an app interaction.  Being the top activity doesn't count while the display
19347        // is sleeping, nor do short foreground services.
19348        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19349            isInteraction = true;
19350            app.fgInteractionTime = 0;
19351        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19352            if (app.fgInteractionTime == 0) {
19353                app.fgInteractionTime = nowElapsed;
19354                isInteraction = false;
19355            } else {
19356                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19357            }
19358        } else {
19359            isInteraction = app.curProcState
19360                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19361            app.fgInteractionTime = 0;
19362        }
19363        if (isInteraction && (!app.reportedInteraction
19364                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19365            app.interactionEventTime = nowElapsed;
19366            String[] packages = app.getPackageList();
19367            if (packages != null) {
19368                for (int i = 0; i < packages.length; i++) {
19369                    mUsageStatsService.reportEvent(packages[i], app.userId,
19370                            UsageEvents.Event.SYSTEM_INTERACTION);
19371                }
19372            }
19373        }
19374        app.reportedInteraction = isInteraction;
19375        if (!isInteraction) {
19376            app.interactionEventTime = 0;
19377        }
19378    }
19379
19380    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19381        if (proc.thread != null) {
19382            if (proc.baseProcessTracker != null) {
19383                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19384            }
19385        }
19386    }
19387
19388    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19389            ProcessRecord TOP_APP, boolean doingAll, long now) {
19390        if (app.thread == null) {
19391            return false;
19392        }
19393
19394        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19395
19396        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19397    }
19398
19399    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19400            boolean oomAdj) {
19401        if (isForeground != proc.foregroundServices) {
19402            proc.foregroundServices = isForeground;
19403            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19404                    proc.info.uid);
19405            if (isForeground) {
19406                if (curProcs == null) {
19407                    curProcs = new ArrayList<ProcessRecord>();
19408                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19409                }
19410                if (!curProcs.contains(proc)) {
19411                    curProcs.add(proc);
19412                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19413                            proc.info.packageName, proc.info.uid);
19414                }
19415            } else {
19416                if (curProcs != null) {
19417                    if (curProcs.remove(proc)) {
19418                        mBatteryStatsService.noteEvent(
19419                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19420                                proc.info.packageName, proc.info.uid);
19421                        if (curProcs.size() <= 0) {
19422                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19423                        }
19424                    }
19425                }
19426            }
19427            if (oomAdj) {
19428                updateOomAdjLocked();
19429            }
19430        }
19431    }
19432
19433    private final ActivityRecord resumedAppLocked() {
19434        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19435        String pkg;
19436        int uid;
19437        if (act != null) {
19438            pkg = act.packageName;
19439            uid = act.info.applicationInfo.uid;
19440        } else {
19441            pkg = null;
19442            uid = -1;
19443        }
19444        // Has the UID or resumed package name changed?
19445        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19446                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19447            if (mCurResumedPackage != null) {
19448                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19449                        mCurResumedPackage, mCurResumedUid);
19450            }
19451            mCurResumedPackage = pkg;
19452            mCurResumedUid = uid;
19453            if (mCurResumedPackage != null) {
19454                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19455                        mCurResumedPackage, mCurResumedUid);
19456            }
19457        }
19458        return act;
19459    }
19460
19461    final boolean updateOomAdjLocked(ProcessRecord app) {
19462        final ActivityRecord TOP_ACT = resumedAppLocked();
19463        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19464        final boolean wasCached = app.cached;
19465
19466        mAdjSeq++;
19467
19468        // This is the desired cached adjusment we want to tell it to use.
19469        // If our app is currently cached, we know it, and that is it.  Otherwise,
19470        // we don't know it yet, and it needs to now be cached we will then
19471        // need to do a complete oom adj.
19472        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19473                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19474        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19475                SystemClock.uptimeMillis());
19476        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19477            // Changed to/from cached state, so apps after it in the LRU
19478            // list may also be changed.
19479            updateOomAdjLocked();
19480        }
19481        return success;
19482    }
19483
19484    final void updateOomAdjLocked() {
19485        final ActivityRecord TOP_ACT = resumedAppLocked();
19486        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19487        final long now = SystemClock.uptimeMillis();
19488        final long nowElapsed = SystemClock.elapsedRealtime();
19489        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19490        final int N = mLruProcesses.size();
19491
19492        if (false) {
19493            RuntimeException e = new RuntimeException();
19494            e.fillInStackTrace();
19495            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19496        }
19497
19498        // Reset state in all uid records.
19499        for (int i=mActiveUids.size()-1; i>=0; i--) {
19500            final UidRecord uidRec = mActiveUids.valueAt(i);
19501            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19502                    "Starting update of " + uidRec);
19503            uidRec.reset();
19504        }
19505
19506        mStackSupervisor.rankTaskLayersIfNeeded();
19507
19508        mAdjSeq++;
19509        mNewNumServiceProcs = 0;
19510        mNewNumAServiceProcs = 0;
19511
19512        final int emptyProcessLimit;
19513        final int cachedProcessLimit;
19514        if (mProcessLimit <= 0) {
19515            emptyProcessLimit = cachedProcessLimit = 0;
19516        } else if (mProcessLimit == 1) {
19517            emptyProcessLimit = 1;
19518            cachedProcessLimit = 0;
19519        } else {
19520            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19521            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19522        }
19523
19524        // Let's determine how many processes we have running vs.
19525        // how many slots we have for background processes; we may want
19526        // to put multiple processes in a slot of there are enough of
19527        // them.
19528        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19529                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19530        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19531        if (numEmptyProcs > cachedProcessLimit) {
19532            // If there are more empty processes than our limit on cached
19533            // processes, then use the cached process limit for the factor.
19534            // This ensures that the really old empty processes get pushed
19535            // down to the bottom, so if we are running low on memory we will
19536            // have a better chance at keeping around more cached processes
19537            // instead of a gazillion empty processes.
19538            numEmptyProcs = cachedProcessLimit;
19539        }
19540        int emptyFactor = numEmptyProcs/numSlots;
19541        if (emptyFactor < 1) emptyFactor = 1;
19542        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19543        if (cachedFactor < 1) cachedFactor = 1;
19544        int stepCached = 0;
19545        int stepEmpty = 0;
19546        int numCached = 0;
19547        int numEmpty = 0;
19548        int numTrimming = 0;
19549
19550        mNumNonCachedProcs = 0;
19551        mNumCachedHiddenProcs = 0;
19552
19553        // First update the OOM adjustment for each of the
19554        // application processes based on their current state.
19555        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19556        int nextCachedAdj = curCachedAdj+1;
19557        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19558        int nextEmptyAdj = curEmptyAdj+2;
19559        for (int i=N-1; i>=0; i--) {
19560            ProcessRecord app = mLruProcesses.get(i);
19561            if (!app.killedByAm && app.thread != null) {
19562                app.procStateChanged = false;
19563                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19564
19565                // If we haven't yet assigned the final cached adj
19566                // to the process, do that now.
19567                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19568                    switch (app.curProcState) {
19569                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19570                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19571                            // This process is a cached process holding activities...
19572                            // assign it the next cached value for that type, and then
19573                            // step that cached level.
19574                            app.curRawAdj = curCachedAdj;
19575                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19576                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19577                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19578                                    + ")");
19579                            if (curCachedAdj != nextCachedAdj) {
19580                                stepCached++;
19581                                if (stepCached >= cachedFactor) {
19582                                    stepCached = 0;
19583                                    curCachedAdj = nextCachedAdj;
19584                                    nextCachedAdj += 2;
19585                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19586                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19587                                    }
19588                                }
19589                            }
19590                            break;
19591                        default:
19592                            // For everything else, assign next empty cached process
19593                            // level and bump that up.  Note that this means that
19594                            // long-running services that have dropped down to the
19595                            // cached level will be treated as empty (since their process
19596                            // state is still as a service), which is what we want.
19597                            app.curRawAdj = curEmptyAdj;
19598                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19599                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19600                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19601                                    + ")");
19602                            if (curEmptyAdj != nextEmptyAdj) {
19603                                stepEmpty++;
19604                                if (stepEmpty >= emptyFactor) {
19605                                    stepEmpty = 0;
19606                                    curEmptyAdj = nextEmptyAdj;
19607                                    nextEmptyAdj += 2;
19608                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19609                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19610                                    }
19611                                }
19612                            }
19613                            break;
19614                    }
19615                }
19616
19617                applyOomAdjLocked(app, true, now, nowElapsed);
19618
19619                // Count the number of process types.
19620                switch (app.curProcState) {
19621                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19622                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19623                        mNumCachedHiddenProcs++;
19624                        numCached++;
19625                        if (numCached > cachedProcessLimit) {
19626                            app.kill("cached #" + numCached, true);
19627                        }
19628                        break;
19629                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19630                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19631                                && app.lastActivityTime < oldTime) {
19632                            app.kill("empty for "
19633                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19634                                    / 1000) + "s", true);
19635                        } else {
19636                            numEmpty++;
19637                            if (numEmpty > emptyProcessLimit) {
19638                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
19639                            }
19640                        }
19641                        break;
19642                    default:
19643                        mNumNonCachedProcs++;
19644                        break;
19645                }
19646
19647                if (app.isolated && app.services.size() <= 0) {
19648                    // If this is an isolated process, and there are no
19649                    // services running in it, then the process is no longer
19650                    // needed.  We agressively kill these because we can by
19651                    // definition not re-use the same process again, and it is
19652                    // good to avoid having whatever code was running in them
19653                    // left sitting around after no longer needed.
19654                    app.kill("isolated not needed", true);
19655                } else {
19656                    // Keeping this process, update its uid.
19657                    final UidRecord uidRec = app.uidRecord;
19658                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19659                        uidRec.curProcState = app.curProcState;
19660                    }
19661                }
19662
19663                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19664                        && !app.killedByAm) {
19665                    numTrimming++;
19666                }
19667            }
19668        }
19669
19670        mNumServiceProcs = mNewNumServiceProcs;
19671
19672        // Now determine the memory trimming level of background processes.
19673        // Unfortunately we need to start at the back of the list to do this
19674        // properly.  We only do this if the number of background apps we
19675        // are managing to keep around is less than half the maximum we desire;
19676        // if we are keeping a good number around, we'll let them use whatever
19677        // memory they want.
19678        final int numCachedAndEmpty = numCached + numEmpty;
19679        int memFactor;
19680        if (numCached <= ProcessList.TRIM_CACHED_APPS
19681                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19682            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19683                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19684            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19685                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19686            } else {
19687                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19688            }
19689        } else {
19690            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19691        }
19692        // We always allow the memory level to go up (better).  We only allow it to go
19693        // down if we are in a state where that is allowed, *and* the total number of processes
19694        // has gone down since last time.
19695        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19696                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19697                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19698        if (memFactor > mLastMemoryLevel) {
19699            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19700                memFactor = mLastMemoryLevel;
19701                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19702            }
19703        }
19704        mLastMemoryLevel = memFactor;
19705        mLastNumProcesses = mLruProcesses.size();
19706        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19707        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19708        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19709            if (mLowRamStartTime == 0) {
19710                mLowRamStartTime = now;
19711            }
19712            int step = 0;
19713            int fgTrimLevel;
19714            switch (memFactor) {
19715                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19716                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19717                    break;
19718                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19719                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19720                    break;
19721                default:
19722                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19723                    break;
19724            }
19725            int factor = numTrimming/3;
19726            int minFactor = 2;
19727            if (mHomeProcess != null) minFactor++;
19728            if (mPreviousProcess != null) minFactor++;
19729            if (factor < minFactor) factor = minFactor;
19730            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19731            for (int i=N-1; i>=0; i--) {
19732                ProcessRecord app = mLruProcesses.get(i);
19733                if (allChanged || app.procStateChanged) {
19734                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19735                    app.procStateChanged = false;
19736                }
19737                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19738                        && !app.killedByAm) {
19739                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19740                        try {
19741                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19742                                    "Trimming memory of " + app.processName + " to " + curLevel);
19743                            app.thread.scheduleTrimMemory(curLevel);
19744                        } catch (RemoteException e) {
19745                        }
19746                        if (false) {
19747                            // For now we won't do this; our memory trimming seems
19748                            // to be good enough at this point that destroying
19749                            // activities causes more harm than good.
19750                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19751                                    && app != mHomeProcess && app != mPreviousProcess) {
19752                                // Need to do this on its own message because the stack may not
19753                                // be in a consistent state at this point.
19754                                // For these apps we will also finish their activities
19755                                // to help them free memory.
19756                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19757                            }
19758                        }
19759                    }
19760                    app.trimMemoryLevel = curLevel;
19761                    step++;
19762                    if (step >= factor) {
19763                        step = 0;
19764                        switch (curLevel) {
19765                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19766                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19767                                break;
19768                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19769                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19770                                break;
19771                        }
19772                    }
19773                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19774                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19775                            && app.thread != null) {
19776                        try {
19777                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19778                                    "Trimming memory of heavy-weight " + app.processName
19779                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19780                            app.thread.scheduleTrimMemory(
19781                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19782                        } catch (RemoteException e) {
19783                        }
19784                    }
19785                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19786                } else {
19787                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19788                            || app.systemNoUi) && app.pendingUiClean) {
19789                        // If this application is now in the background and it
19790                        // had done UI, then give it the special trim level to
19791                        // have it free UI resources.
19792                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19793                        if (app.trimMemoryLevel < level && app.thread != null) {
19794                            try {
19795                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19796                                        "Trimming memory of bg-ui " + app.processName
19797                                        + " to " + level);
19798                                app.thread.scheduleTrimMemory(level);
19799                            } catch (RemoteException e) {
19800                            }
19801                        }
19802                        app.pendingUiClean = false;
19803                    }
19804                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19805                        try {
19806                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19807                                    "Trimming memory of fg " + app.processName
19808                                    + " to " + fgTrimLevel);
19809                            app.thread.scheduleTrimMemory(fgTrimLevel);
19810                        } catch (RemoteException e) {
19811                        }
19812                    }
19813                    app.trimMemoryLevel = fgTrimLevel;
19814                }
19815            }
19816        } else {
19817            if (mLowRamStartTime != 0) {
19818                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19819                mLowRamStartTime = 0;
19820            }
19821            for (int i=N-1; i>=0; i--) {
19822                ProcessRecord app = mLruProcesses.get(i);
19823                if (allChanged || app.procStateChanged) {
19824                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19825                    app.procStateChanged = false;
19826                }
19827                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19828                        || app.systemNoUi) && app.pendingUiClean) {
19829                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19830                            && app.thread != null) {
19831                        try {
19832                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19833                                    "Trimming memory of ui hidden " + app.processName
19834                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19835                            app.thread.scheduleTrimMemory(
19836                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19837                        } catch (RemoteException e) {
19838                        }
19839                    }
19840                    app.pendingUiClean = false;
19841                }
19842                app.trimMemoryLevel = 0;
19843            }
19844        }
19845
19846        if (mAlwaysFinishActivities) {
19847            // Need to do this on its own message because the stack may not
19848            // be in a consistent state at this point.
19849            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19850        }
19851
19852        if (allChanged) {
19853            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19854        }
19855
19856        // Update from any uid changes.
19857        for (int i=mActiveUids.size()-1; i>=0; i--) {
19858            final UidRecord uidRec = mActiveUids.valueAt(i);
19859            int uidChange = UidRecord.CHANGE_PROCSTATE;
19860            if (uidRec.setProcState != uidRec.curProcState) {
19861                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19862                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19863                        + " to " + uidRec.curProcState);
19864                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
19865                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
19866                        uidRec.lastBackgroundTime = nowElapsed;
19867                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
19868                            // Note: the background settle time is in elapsed realtime, while
19869                            // the handler time base is uptime.  All this means is that we may
19870                            // stop background uids later than we had intended, but that only
19871                            // happens because the device was sleeping so we are okay anyway.
19872                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
19873                        }
19874                    }
19875                } else {
19876                    if (uidRec.idle) {
19877                        uidChange = UidRecord.CHANGE_ACTIVE;
19878                        uidRec.idle = false;
19879                    }
19880                    uidRec.lastBackgroundTime = 0;
19881                }
19882                uidRec.setProcState = uidRec.curProcState;
19883                enqueueUidChangeLocked(uidRec, -1, uidChange);
19884                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
19885            }
19886        }
19887
19888        if (mProcessStats.shouldWriteNowLocked(now)) {
19889            mHandler.post(new Runnable() {
19890                @Override public void run() {
19891                    synchronized (ActivityManagerService.this) {
19892                        mProcessStats.writeStateAsyncLocked();
19893                    }
19894                }
19895            });
19896        }
19897
19898        if (DEBUG_OOM_ADJ) {
19899            final long duration = SystemClock.uptimeMillis() - now;
19900            if (false) {
19901                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19902                        new RuntimeException("here").fillInStackTrace());
19903            } else {
19904                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19905            }
19906        }
19907    }
19908
19909    final void idleUids() {
19910        synchronized (this) {
19911            final long nowElapsed = SystemClock.elapsedRealtime();
19912            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
19913            long nextTime = 0;
19914            for (int i=mActiveUids.size()-1; i>=0; i--) {
19915                final UidRecord uidRec = mActiveUids.valueAt(i);
19916                final long bgTime = uidRec.lastBackgroundTime;
19917                if (bgTime > 0 && !uidRec.idle) {
19918                    if (bgTime <= maxBgTime) {
19919                        uidRec.idle = true;
19920                        doStopUidLocked(uidRec.uid, uidRec);
19921                    } else {
19922                        if (nextTime == 0 || nextTime > bgTime) {
19923                            nextTime = bgTime;
19924                        }
19925                    }
19926                }
19927            }
19928            if (nextTime > 0) {
19929                mHandler.removeMessages(IDLE_UIDS_MSG);
19930                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
19931                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
19932            }
19933        }
19934    }
19935
19936    final void runInBackgroundDisabled(int uid) {
19937        synchronized (this) {
19938            UidRecord uidRec = mActiveUids.get(uid);
19939            if (uidRec != null) {
19940                // This uid is actually running...  should it be considered background now?
19941                if (uidRec.idle) {
19942                    doStopUidLocked(uidRec.uid, uidRec);
19943                }
19944            } else {
19945                // This uid isn't actually running...  still send a report about it being "stopped".
19946                doStopUidLocked(uid, null);
19947            }
19948        }
19949    }
19950
19951    final void doStopUidLocked(int uid, final UidRecord uidRec) {
19952        mServices.stopInBackgroundLocked(uid);
19953        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
19954    }
19955
19956    final void trimApplications() {
19957        synchronized (this) {
19958            int i;
19959
19960            // First remove any unused application processes whose package
19961            // has been removed.
19962            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19963                final ProcessRecord app = mRemovedProcesses.get(i);
19964                if (app.activities.size() == 0
19965                        && app.curReceiver == null && app.services.size() == 0) {
19966                    Slog.i(
19967                        TAG, "Exiting empty application process "
19968                        + app.processName + " ("
19969                        + (app.thread != null ? app.thread.asBinder() : null)
19970                        + ")\n");
19971                    if (app.pid > 0 && app.pid != MY_PID) {
19972                        app.kill("empty", false);
19973                    } else {
19974                        try {
19975                            app.thread.scheduleExit();
19976                        } catch (Exception e) {
19977                            // Ignore exceptions.
19978                        }
19979                    }
19980                    cleanUpApplicationRecordLocked(app, false, true, -1);
19981                    mRemovedProcesses.remove(i);
19982
19983                    if (app.persistent) {
19984                        addAppLocked(app.info, false, null /* ABI override */);
19985                    }
19986                }
19987            }
19988
19989            // Now update the oom adj for all processes.
19990            updateOomAdjLocked();
19991        }
19992    }
19993
19994    /** This method sends the specified signal to each of the persistent apps */
19995    public void signalPersistentProcesses(int sig) throws RemoteException {
19996        if (sig != Process.SIGNAL_USR1) {
19997            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19998        }
19999
20000        synchronized (this) {
20001            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20002                    != PackageManager.PERMISSION_GRANTED) {
20003                throw new SecurityException("Requires permission "
20004                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20005            }
20006
20007            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20008                ProcessRecord r = mLruProcesses.get(i);
20009                if (r.thread != null && r.persistent) {
20010                    Process.sendSignal(r.pid, sig);
20011                }
20012            }
20013        }
20014    }
20015
20016    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20017        if (proc == null || proc == mProfileProc) {
20018            proc = mProfileProc;
20019            profileType = mProfileType;
20020            clearProfilerLocked();
20021        }
20022        if (proc == null) {
20023            return;
20024        }
20025        try {
20026            proc.thread.profilerControl(false, null, profileType);
20027        } catch (RemoteException e) {
20028            throw new IllegalStateException("Process disappeared");
20029        }
20030    }
20031
20032    private void clearProfilerLocked() {
20033        if (mProfileFd != null) {
20034            try {
20035                mProfileFd.close();
20036            } catch (IOException e) {
20037            }
20038        }
20039        mProfileApp = null;
20040        mProfileProc = null;
20041        mProfileFile = null;
20042        mProfileType = 0;
20043        mAutoStopProfiler = false;
20044        mSamplingInterval = 0;
20045    }
20046
20047    public boolean profileControl(String process, int userId, boolean start,
20048            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20049
20050        try {
20051            synchronized (this) {
20052                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20053                // its own permission.
20054                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20055                        != PackageManager.PERMISSION_GRANTED) {
20056                    throw new SecurityException("Requires permission "
20057                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20058                }
20059
20060                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20061                    throw new IllegalArgumentException("null profile info or fd");
20062                }
20063
20064                ProcessRecord proc = null;
20065                if (process != null) {
20066                    proc = findProcessLocked(process, userId, "profileControl");
20067                }
20068
20069                if (start && (proc == null || proc.thread == null)) {
20070                    throw new IllegalArgumentException("Unknown process: " + process);
20071                }
20072
20073                if (start) {
20074                    stopProfilerLocked(null, 0);
20075                    setProfileApp(proc.info, proc.processName, profilerInfo);
20076                    mProfileProc = proc;
20077                    mProfileType = profileType;
20078                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20079                    try {
20080                        fd = fd.dup();
20081                    } catch (IOException e) {
20082                        fd = null;
20083                    }
20084                    profilerInfo.profileFd = fd;
20085                    proc.thread.profilerControl(start, profilerInfo, profileType);
20086                    fd = null;
20087                    mProfileFd = null;
20088                } else {
20089                    stopProfilerLocked(proc, profileType);
20090                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20091                        try {
20092                            profilerInfo.profileFd.close();
20093                        } catch (IOException e) {
20094                        }
20095                    }
20096                }
20097
20098                return true;
20099            }
20100        } catch (RemoteException e) {
20101            throw new IllegalStateException("Process disappeared");
20102        } finally {
20103            if (profilerInfo != null && profilerInfo.profileFd != null) {
20104                try {
20105                    profilerInfo.profileFd.close();
20106                } catch (IOException e) {
20107                }
20108            }
20109        }
20110    }
20111
20112    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20113        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20114                userId, true, ALLOW_FULL_ONLY, callName, null);
20115        ProcessRecord proc = null;
20116        try {
20117            int pid = Integer.parseInt(process);
20118            synchronized (mPidsSelfLocked) {
20119                proc = mPidsSelfLocked.get(pid);
20120            }
20121        } catch (NumberFormatException e) {
20122        }
20123
20124        if (proc == null) {
20125            ArrayMap<String, SparseArray<ProcessRecord>> all
20126                    = mProcessNames.getMap();
20127            SparseArray<ProcessRecord> procs = all.get(process);
20128            if (procs != null && procs.size() > 0) {
20129                proc = procs.valueAt(0);
20130                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20131                    for (int i=1; i<procs.size(); i++) {
20132                        ProcessRecord thisProc = procs.valueAt(i);
20133                        if (thisProc.userId == userId) {
20134                            proc = thisProc;
20135                            break;
20136                        }
20137                    }
20138                }
20139            }
20140        }
20141
20142        return proc;
20143    }
20144
20145    public boolean dumpHeap(String process, int userId, boolean managed,
20146            String path, ParcelFileDescriptor fd) throws RemoteException {
20147
20148        try {
20149            synchronized (this) {
20150                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20151                // its own permission (same as profileControl).
20152                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20153                        != PackageManager.PERMISSION_GRANTED) {
20154                    throw new SecurityException("Requires permission "
20155                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20156                }
20157
20158                if (fd == null) {
20159                    throw new IllegalArgumentException("null fd");
20160                }
20161
20162                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20163                if (proc == null || proc.thread == null) {
20164                    throw new IllegalArgumentException("Unknown process: " + process);
20165                }
20166
20167                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20168                if (!isDebuggable) {
20169                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20170                        throw new SecurityException("Process not debuggable: " + proc);
20171                    }
20172                }
20173
20174                proc.thread.dumpHeap(managed, path, fd);
20175                fd = null;
20176                return true;
20177            }
20178        } catch (RemoteException e) {
20179            throw new IllegalStateException("Process disappeared");
20180        } finally {
20181            if (fd != null) {
20182                try {
20183                    fd.close();
20184                } catch (IOException e) {
20185                }
20186            }
20187        }
20188    }
20189
20190    @Override
20191    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20192            String reportPackage) {
20193        if (processName != null) {
20194            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20195                    "setDumpHeapDebugLimit()");
20196        } else {
20197            synchronized (mPidsSelfLocked) {
20198                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20199                if (proc == null) {
20200                    throw new SecurityException("No process found for calling pid "
20201                            + Binder.getCallingPid());
20202                }
20203                if (!Build.IS_DEBUGGABLE
20204                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20205                    throw new SecurityException("Not running a debuggable build");
20206                }
20207                processName = proc.processName;
20208                uid = proc.uid;
20209                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20210                    throw new SecurityException("Package " + reportPackage + " is not running in "
20211                            + proc);
20212                }
20213            }
20214        }
20215        synchronized (this) {
20216            if (maxMemSize > 0) {
20217                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20218            } else {
20219                if (uid != 0) {
20220                    mMemWatchProcesses.remove(processName, uid);
20221                } else {
20222                    mMemWatchProcesses.getMap().remove(processName);
20223                }
20224            }
20225        }
20226    }
20227
20228    @Override
20229    public void dumpHeapFinished(String path) {
20230        synchronized (this) {
20231            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20232                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20233                        + " does not match last pid " + mMemWatchDumpPid);
20234                return;
20235            }
20236            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20237                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20238                        + " does not match last path " + mMemWatchDumpFile);
20239                return;
20240            }
20241            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20242            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20243        }
20244    }
20245
20246    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20247    public void monitor() {
20248        synchronized (this) { }
20249    }
20250
20251    void onCoreSettingsChange(Bundle settings) {
20252        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20253            ProcessRecord processRecord = mLruProcesses.get(i);
20254            try {
20255                if (processRecord.thread != null) {
20256                    processRecord.thread.setCoreSettings(settings);
20257                }
20258            } catch (RemoteException re) {
20259                /* ignore */
20260            }
20261        }
20262    }
20263
20264    // Multi-user methods
20265
20266    /**
20267     * Start user, if its not already running, but don't bring it to foreground.
20268     */
20269    @Override
20270    public boolean startUserInBackground(final int userId) {
20271        return mUserController.startUser(userId, /* foreground */ false);
20272    }
20273
20274    @Override
20275    public boolean unlockUser(int userId, byte[] token) {
20276        return mUserController.unlockUser(userId, token);
20277    }
20278
20279    @Override
20280    public boolean switchUser(final int targetUserId) {
20281        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20282        UserInfo currentUserInfo;
20283        UserInfo targetUserInfo;
20284        synchronized (this) {
20285            int currentUserId = mUserController.getCurrentUserIdLocked();
20286            currentUserInfo = mUserController.getUserInfo(currentUserId);
20287            targetUserInfo = mUserController.getUserInfo(targetUserId);
20288            if (targetUserInfo == null) {
20289                Slog.w(TAG, "No user info for user #" + targetUserId);
20290                return false;
20291            }
20292            if (targetUserInfo.isManagedProfile()) {
20293                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20294                return false;
20295            }
20296            mUserController.setTargetUserIdLocked(targetUserId);
20297        }
20298        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20299        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20300        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20301        return true;
20302    }
20303
20304    void scheduleStartProfilesLocked() {
20305        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20306            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20307                    DateUtils.SECOND_IN_MILLIS);
20308        }
20309    }
20310
20311    @Override
20312    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20313        return mUserController.stopUser(userId, force, callback);
20314    }
20315
20316    @Override
20317    public UserInfo getCurrentUser() {
20318        return mUserController.getCurrentUser();
20319    }
20320
20321    @Override
20322    public boolean isUserRunning(int userId, int flags) {
20323        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20324                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20325            String msg = "Permission Denial: isUserRunning() from pid="
20326                    + Binder.getCallingPid()
20327                    + ", uid=" + Binder.getCallingUid()
20328                    + " requires " + INTERACT_ACROSS_USERS;
20329            Slog.w(TAG, msg);
20330            throw new SecurityException(msg);
20331        }
20332        synchronized (this) {
20333            return mUserController.isUserRunningLocked(userId, flags);
20334        }
20335    }
20336
20337    @Override
20338    public int[] getRunningUserIds() {
20339        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20340                != PackageManager.PERMISSION_GRANTED) {
20341            String msg = "Permission Denial: isUserRunning() from pid="
20342                    + Binder.getCallingPid()
20343                    + ", uid=" + Binder.getCallingUid()
20344                    + " requires " + INTERACT_ACROSS_USERS;
20345            Slog.w(TAG, msg);
20346            throw new SecurityException(msg);
20347        }
20348        synchronized (this) {
20349            return mUserController.getStartedUserArrayLocked();
20350        }
20351    }
20352
20353    @Override
20354    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20355        mUserController.registerUserSwitchObserver(observer);
20356    }
20357
20358    @Override
20359    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20360        mUserController.unregisterUserSwitchObserver(observer);
20361    }
20362
20363    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20364        if (info == null) return null;
20365        ApplicationInfo newInfo = new ApplicationInfo(info);
20366        newInfo.initForUser(userId);
20367        return newInfo;
20368    }
20369
20370    public boolean isUserStopped(int userId) {
20371        synchronized (this) {
20372            return mUserController.getStartedUserStateLocked(userId) == null;
20373        }
20374    }
20375
20376    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20377        if (aInfo == null
20378                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20379            return aInfo;
20380        }
20381
20382        ActivityInfo info = new ActivityInfo(aInfo);
20383        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20384        return info;
20385    }
20386
20387    private boolean processSanityChecksLocked(ProcessRecord process) {
20388        if (process == null || process.thread == null) {
20389            return false;
20390        }
20391
20392        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20393        if (!isDebuggable) {
20394            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20395                return false;
20396            }
20397        }
20398
20399        return true;
20400    }
20401
20402    public boolean startBinderTracking() throws RemoteException {
20403        synchronized (this) {
20404            mBinderTransactionTrackingEnabled = true;
20405            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20406            // permission (same as profileControl).
20407            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20408                    != PackageManager.PERMISSION_GRANTED) {
20409                throw new SecurityException("Requires permission "
20410                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20411            }
20412
20413            for (int i = 0; i < mLruProcesses.size(); i++) {
20414                ProcessRecord process = mLruProcesses.get(i);
20415                if (!processSanityChecksLocked(process)) {
20416                    continue;
20417                }
20418                try {
20419                    process.thread.startBinderTracking();
20420                } catch (RemoteException e) {
20421                    Log.v(TAG, "Process disappared");
20422                }
20423            }
20424            return true;
20425        }
20426    }
20427
20428    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20429        try {
20430            synchronized (this) {
20431                mBinderTransactionTrackingEnabled = false;
20432                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20433                // permission (same as profileControl).
20434                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20435                        != PackageManager.PERMISSION_GRANTED) {
20436                    throw new SecurityException("Requires permission "
20437                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20438                }
20439
20440                if (fd == null) {
20441                    throw new IllegalArgumentException("null fd");
20442                }
20443
20444                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20445                pw.println("Binder transaction traces for all processes.\n");
20446                for (ProcessRecord process : mLruProcesses) {
20447                    if (!processSanityChecksLocked(process)) {
20448                        continue;
20449                    }
20450
20451                    pw.println("Traces for process: " + process.processName);
20452                    pw.flush();
20453                    try {
20454                        TransferPipe tp = new TransferPipe();
20455                        try {
20456                            process.thread.stopBinderTrackingAndDump(
20457                                    tp.getWriteFd().getFileDescriptor());
20458                            tp.go(fd.getFileDescriptor());
20459                        } finally {
20460                            tp.kill();
20461                        }
20462                    } catch (IOException e) {
20463                        pw.println("Failure while dumping IPC traces from " + process +
20464                                ".  Exception: " + e);
20465                        pw.flush();
20466                    } catch (RemoteException e) {
20467                        pw.println("Got a RemoteException while dumping IPC traces from " +
20468                                process + ".  Exception: " + e);
20469                        pw.flush();
20470                    }
20471                }
20472                fd = null;
20473                return true;
20474            }
20475        } finally {
20476            if (fd != null) {
20477                try {
20478                    fd.close();
20479                } catch (IOException e) {
20480                }
20481            }
20482        }
20483    }
20484
20485    private final class LocalService extends ActivityManagerInternal {
20486        @Override
20487        public void onWakefulnessChanged(int wakefulness) {
20488            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20489        }
20490
20491        @Override
20492        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20493                String processName, String abiOverride, int uid, Runnable crashHandler) {
20494            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20495                    processName, abiOverride, uid, crashHandler);
20496        }
20497
20498        @Override
20499        public SleepToken acquireSleepToken(String tag) {
20500            Preconditions.checkNotNull(tag);
20501
20502            synchronized (ActivityManagerService.this) {
20503                SleepTokenImpl token = new SleepTokenImpl(tag);
20504                mSleepTokens.add(token);
20505                updateSleepIfNeededLocked();
20506                return token;
20507            }
20508        }
20509
20510        @Override
20511        public ComponentName getHomeActivityForUser(int userId) {
20512            synchronized (ActivityManagerService.this) {
20513                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20514                return homeActivity == null ? null : homeActivity.realActivity;
20515            }
20516        }
20517
20518        @Override
20519        public void onUserRemoved(int userId) {
20520            synchronized (ActivityManagerService.this) {
20521                ActivityManagerService.this.onUserStoppedLocked(userId);
20522            }
20523        }
20524
20525        @Override
20526        public void onLocalVoiceInteractionStarted(IBinder activity,
20527                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20528            synchronized (ActivityManagerService.this) {
20529                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20530                        voiceSession, voiceInteractor);
20531            }
20532        }
20533    }
20534
20535    private final class SleepTokenImpl extends SleepToken {
20536        private final String mTag;
20537        private final long mAcquireTime;
20538
20539        public SleepTokenImpl(String tag) {
20540            mTag = tag;
20541            mAcquireTime = SystemClock.uptimeMillis();
20542        }
20543
20544        @Override
20545        public void release() {
20546            synchronized (ActivityManagerService.this) {
20547                if (mSleepTokens.remove(this)) {
20548                    updateSleepIfNeededLocked();
20549                }
20550            }
20551        }
20552
20553        @Override
20554        public String toString() {
20555            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20556        }
20557    }
20558
20559    /**
20560     * An implementation of IAppTask, that allows an app to manage its own tasks via
20561     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20562     * only the process that calls getAppTasks() can call the AppTask methods.
20563     */
20564    class AppTaskImpl extends IAppTask.Stub {
20565        private int mTaskId;
20566        private int mCallingUid;
20567
20568        public AppTaskImpl(int taskId, int callingUid) {
20569            mTaskId = taskId;
20570            mCallingUid = callingUid;
20571        }
20572
20573        private void checkCaller() {
20574            if (mCallingUid != Binder.getCallingUid()) {
20575                throw new SecurityException("Caller " + mCallingUid
20576                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20577            }
20578        }
20579
20580        @Override
20581        public void finishAndRemoveTask() {
20582            checkCaller();
20583
20584            synchronized (ActivityManagerService.this) {
20585                long origId = Binder.clearCallingIdentity();
20586                try {
20587                    // We remove the task from recents to preserve backwards
20588                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20589                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20590                    }
20591                } finally {
20592                    Binder.restoreCallingIdentity(origId);
20593                }
20594            }
20595        }
20596
20597        @Override
20598        public ActivityManager.RecentTaskInfo getTaskInfo() {
20599            checkCaller();
20600
20601            synchronized (ActivityManagerService.this) {
20602                long origId = Binder.clearCallingIdentity();
20603                try {
20604                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20605                    if (tr == null) {
20606                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20607                    }
20608                    return createRecentTaskInfoFromTaskRecord(tr);
20609                } finally {
20610                    Binder.restoreCallingIdentity(origId);
20611                }
20612            }
20613        }
20614
20615        @Override
20616        public void moveToFront() {
20617            checkCaller();
20618            // Will bring task to front if it already has a root activity.
20619            final long origId = Binder.clearCallingIdentity();
20620            try {
20621                startActivityFromRecentsInner(mTaskId, null);
20622            } finally {
20623                Binder.restoreCallingIdentity(origId);
20624            }
20625        }
20626
20627        @Override
20628        public int startActivity(IBinder whoThread, String callingPackage,
20629                Intent intent, String resolvedType, Bundle bOptions) {
20630            checkCaller();
20631
20632            int callingUser = UserHandle.getCallingUserId();
20633            TaskRecord tr;
20634            IApplicationThread appThread;
20635            synchronized (ActivityManagerService.this) {
20636                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20637                if (tr == null) {
20638                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20639                }
20640                appThread = ApplicationThreadNative.asInterface(whoThread);
20641                if (appThread == null) {
20642                    throw new IllegalArgumentException("Bad app thread " + appThread);
20643                }
20644            }
20645            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
20646                    resolvedType, null, null, null, null, 0, 0, null, null,
20647                    null, bOptions, false, callingUser, null, tr);
20648        }
20649
20650        @Override
20651        public void setExcludeFromRecents(boolean exclude) {
20652            checkCaller();
20653
20654            synchronized (ActivityManagerService.this) {
20655                long origId = Binder.clearCallingIdentity();
20656                try {
20657                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20658                    if (tr == null) {
20659                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20660                    }
20661                    Intent intent = tr.getBaseIntent();
20662                    if (exclude) {
20663                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20664                    } else {
20665                        intent.setFlags(intent.getFlags()
20666                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20667                    }
20668                } finally {
20669                    Binder.restoreCallingIdentity(origId);
20670                }
20671            }
20672        }
20673    }
20674
20675    /**
20676     * Kill processes for the user with id userId and that depend on the package named packageName
20677     */
20678    @Override
20679    public void killPackageDependents(String packageName, int userId) {
20680        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
20681        if (packageName == null) {
20682            throw new NullPointerException(
20683                    "Cannot kill the dependents of a package without its name.");
20684        }
20685
20686        long callingId = Binder.clearCallingIdentity();
20687        IPackageManager pm = AppGlobals.getPackageManager();
20688        int pkgUid = -1;
20689        try {
20690            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
20691        } catch (RemoteException e) {
20692        }
20693        if (pkgUid == -1) {
20694            throw new IllegalArgumentException(
20695                    "Cannot kill dependents of non-existing package " + packageName);
20696        }
20697        try {
20698            synchronized(this) {
20699                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
20700                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
20701                        "dep: " + packageName);
20702            }
20703        } finally {
20704            Binder.restoreCallingIdentity(callingId);
20705        }
20706    }
20707}
20708